2009-02-21 19:23:54 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
2012-12-10 06:15:42 +00:00
|
|
|
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
2009-02-21 19:23:54 +00:00
|
|
|
|
2009-09-08 19:58:05 +00:00
|
|
|
###############################################################################
|
|
|
|
# OpenLP - Open Source Lyrics Projection #
|
|
|
|
# --------------------------------------------------------------------------- #
|
2017-12-29 09:15:48 +00:00
|
|
|
# Copyright (c) 2008-2018 OpenLP Developers #
|
2009-09-08 19:58:05 +00:00
|
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
# 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 #
|
|
|
|
###############################################################################
|
2013-02-01 21:34:23 +00:00
|
|
|
"""
|
|
|
|
The service manager sets up, loads, saves and manages services.
|
|
|
|
"""
|
2013-12-26 08:56:53 +00:00
|
|
|
import html
|
2016-03-31 16:34:22 +00:00
|
|
|
import json
|
2011-02-04 12:57:48 +00:00
|
|
|
import os
|
2011-08-28 20:51:44 +00:00
|
|
|
import shutil
|
2009-06-20 11:23:34 +00:00
|
|
|
import zipfile
|
2017-12-27 16:06:36 +00:00
|
|
|
from contextlib import suppress
|
2012-01-15 01:21:35 +00:00
|
|
|
from datetime import datetime, timedelta
|
2017-12-27 16:06:36 +00:00
|
|
|
from tempfile import NamedTemporaryFile, mkstemp
|
2009-02-21 19:23:54 +00:00
|
|
|
|
2015-11-07 00:49:40 +00:00
|
|
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
2010-03-03 17:48:37 +00:00
|
|
|
|
2017-11-18 23:14:28 +00:00
|
|
|
from openlp.core.common import ThemeLevel, delete_file
|
2016-03-31 16:34:22 +00:00
|
|
|
from openlp.core.common.actions import ActionList, CategoryOrder
|
2017-10-07 07:05:07 +00:00
|
|
|
from openlp.core.common.applocation import AppLocation
|
|
|
|
from openlp.core.common.i18n import UiStrings, format_time, translate
|
2017-12-30 08:08:10 +00:00
|
|
|
from openlp.core.common.json import OpenLPJsonDecoder, OpenLPJsonEncoder
|
2017-10-23 22:09:57 +00:00
|
|
|
from openlp.core.common.mixins import LogMixin, RegistryProperties
|
2017-11-19 21:57:38 +00:00
|
|
|
from openlp.core.common.path import Path, create_paths, str_to_path
|
2017-10-23 22:09:57 +00:00
|
|
|
from openlp.core.common.registry import Registry, RegistryBase
|
2017-10-07 07:05:07 +00:00
|
|
|
from openlp.core.common.settings import Settings
|
2016-04-17 19:32:15 +00:00
|
|
|
from openlp.core.lib import ServiceItem, ItemCapabilities, PluginStatus, build_icon
|
2018-01-06 09:55:19 +00:00
|
|
|
from openlp.core.lib.exceptions import ValidationError
|
2013-01-11 00:19:11 +00:00
|
|
|
from openlp.core.lib.ui import critical_error_message_box, create_widget_action, find_and_set_in_combo_box
|
2013-02-02 19:49:56 +00:00
|
|
|
from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm
|
2017-10-23 22:09:57 +00:00
|
|
|
from openlp.core.widgets.dialogs import FileDialog
|
|
|
|
from openlp.core.widgets.toolbar import OpenLPToolbar
|
2013-02-02 19:49:56 +00:00
|
|
|
|
2013-02-01 21:34:23 +00:00
|
|
|
|
2015-11-07 00:49:40 +00:00
|
|
|
class ServiceManagerList(QtWidgets.QTreeWidget):
|
2013-02-02 19:49:56 +00:00
|
|
|
"""
|
|
|
|
Set up key bindings and mouse behaviour for the service list
|
|
|
|
"""
|
2013-12-26 08:56:53 +00:00
|
|
|
def __init__(self, service_manager, parent=None):
|
2013-02-01 21:34:23 +00:00
|
|
|
"""
|
|
|
|
Constructor
|
|
|
|
"""
|
2013-07-18 14:32:23 +00:00
|
|
|
super(ServiceManagerList, self).__init__(parent)
|
2017-10-23 22:09:57 +00:00
|
|
|
self.setDragDropMode(QtWidgets.QAbstractItemView.DragDrop)
|
|
|
|
self.setAlternatingRowColors(True)
|
|
|
|
self.setHeaderHidden(True)
|
|
|
|
self.setExpandsOnDoubleClick(False)
|
2013-12-26 08:56:53 +00:00
|
|
|
self.service_manager = service_manager
|
2013-02-02 19:49:56 +00:00
|
|
|
|
2017-10-23 22:09:57 +00:00
|
|
|
def dragEnterEvent(self, event):
|
|
|
|
"""
|
|
|
|
React to a drag enter event
|
|
|
|
"""
|
|
|
|
event.accept()
|
|
|
|
|
|
|
|
def dragMoveEvent(self, event):
|
|
|
|
"""
|
|
|
|
React to a drage move event
|
|
|
|
"""
|
|
|
|
event.accept()
|
|
|
|
|
2013-02-02 19:49:56 +00:00
|
|
|
def keyPressEvent(self, event):
|
|
|
|
"""
|
|
|
|
Capture Key press and respond accordingly.
|
2014-01-01 09:33:07 +00:00
|
|
|
:param event:
|
2013-02-02 19:49:56 +00:00
|
|
|
"""
|
|
|
|
if isinstance(event, QtGui.QKeyEvent):
|
|
|
|
# here accept the event and do something
|
|
|
|
if event.key() == QtCore.Qt.Key_Up:
|
2013-12-26 08:56:53 +00:00
|
|
|
self.service_manager.on_move_selection_up()
|
2013-02-02 19:49:56 +00:00
|
|
|
event.accept()
|
|
|
|
elif event.key() == QtCore.Qt.Key_Down:
|
2013-12-26 08:56:53 +00:00
|
|
|
self.service_manager.on_move_selection_down()
|
2013-02-02 19:49:56 +00:00
|
|
|
event.accept()
|
2017-06-13 15:49:48 +00:00
|
|
|
elif event.key() == QtCore.Qt.Key_Right:
|
|
|
|
self.service_manager.on_expand_selection()
|
|
|
|
event.accept()
|
|
|
|
elif event.key() == QtCore.Qt.Key_Left:
|
|
|
|
self.service_manager.on_collapse_selection()
|
|
|
|
event.accept()
|
2013-02-02 19:49:56 +00:00
|
|
|
elif event.key() == QtCore.Qt.Key_Delete:
|
2013-12-30 19:50:34 +00:00
|
|
|
self.service_manager.on_delete_from_service()
|
2013-02-02 19:49:56 +00:00
|
|
|
event.accept()
|
|
|
|
event.ignore()
|
|
|
|
else:
|
|
|
|
event.ignore()
|
|
|
|
|
|
|
|
def mouseMoveEvent(self, event):
|
|
|
|
"""
|
2013-03-29 12:53:07 +00:00
|
|
|
Drag and drop event does not care what data is selected as the recipient will use events to request the data
|
|
|
|
move just tell it what plugin to call
|
2014-01-01 09:33:07 +00:00
|
|
|
:param event:
|
2013-02-02 19:49:56 +00:00
|
|
|
"""
|
|
|
|
if event.buttons() != QtCore.Qt.LeftButton:
|
|
|
|
event.ignore()
|
|
|
|
return
|
|
|
|
if not self.itemAt(self.mapFromGlobal(QtGui.QCursor.pos())):
|
|
|
|
event.ignore()
|
|
|
|
return
|
|
|
|
drag = QtGui.QDrag(self)
|
|
|
|
mime_data = QtCore.QMimeData()
|
|
|
|
drag.setMimeData(mime_data)
|
2013-08-31 18:17:38 +00:00
|
|
|
mime_data.setText('ServiceManager')
|
2015-11-07 00:49:40 +00:00
|
|
|
drag.exec(QtCore.Qt.CopyAction)
|
2013-02-02 19:49:56 +00:00
|
|
|
|
2013-02-01 21:34:23 +00:00
|
|
|
|
2013-12-30 19:50:34 +00:00
|
|
|
class Ui_ServiceManager(object):
|
2013-02-02 19:49:56 +00:00
|
|
|
"""
|
|
|
|
UI part of the Service Manager
|
|
|
|
"""
|
|
|
|
def setup_ui(self, widget):
|
|
|
|
"""
|
|
|
|
Define the UI
|
2014-01-01 09:33:07 +00:00
|
|
|
:param widget:
|
2013-02-02 19:49:56 +00:00
|
|
|
"""
|
2013-12-30 19:50:34 +00:00
|
|
|
# start with the layout
|
2015-11-07 00:49:40 +00:00
|
|
|
self.layout = QtWidgets.QVBoxLayout(widget)
|
2013-12-30 19:50:34 +00:00
|
|
|
self.layout.setSpacing(0)
|
2015-11-07 00:49:40 +00:00
|
|
|
self.layout.setContentsMargins(0, 0, 0, 0)
|
2013-02-02 19:49:56 +00:00
|
|
|
# Create the top toolbar
|
2017-10-23 22:09:57 +00:00
|
|
|
self.toolbar = OpenLPToolbar(self)
|
2013-08-31 18:17:38 +00:00
|
|
|
self.toolbar.add_toolbar_action('newService', text=UiStrings().NewService, icon=':/general/general_new.png',
|
2013-12-24 15:55:01 +00:00
|
|
|
tooltip=UiStrings().CreateService, triggers=self.on_new_service_clicked)
|
2013-08-31 18:17:38 +00:00
|
|
|
self.toolbar.add_toolbar_action('openService', text=UiStrings().OpenService,
|
2013-12-24 15:55:01 +00:00
|
|
|
icon=':/general/general_open.png',
|
|
|
|
tooltip=translate('OpenLP.ServiceManager', 'Load an existing service.'),
|
|
|
|
triggers=self.on_load_service_clicked)
|
2013-08-31 18:17:38 +00:00
|
|
|
self.toolbar.add_toolbar_action('saveService', text=UiStrings().SaveService,
|
2013-12-24 15:55:01 +00:00
|
|
|
icon=':/general/general_save.png',
|
2013-12-24 21:24:52 +00:00
|
|
|
tooltip=translate('OpenLP.ServiceManager', 'Save this service.'),
|
2013-12-24 15:55:01 +00:00
|
|
|
triggers=self.decide_save_method)
|
2013-02-02 19:49:56 +00:00
|
|
|
self.toolbar.addSeparator()
|
2016-05-20 16:22:06 +00:00
|
|
|
self.theme_label = QtWidgets.QLabel('{theme}:'.format(theme=UiStrings().Theme), widget)
|
2015-11-07 00:49:40 +00:00
|
|
|
self.theme_label.setContentsMargins(3, 3, 3, 3)
|
2013-08-31 18:17:38 +00:00
|
|
|
self.theme_label.setObjectName('theme_label')
|
2013-03-07 06:48:09 +00:00
|
|
|
self.toolbar.add_toolbar_widget(self.theme_label)
|
2015-11-07 00:49:40 +00:00
|
|
|
self.theme_combo_box = QtWidgets.QComboBox(self.toolbar)
|
2013-02-02 19:49:56 +00:00
|
|
|
self.theme_combo_box.setToolTip(translate('OpenLP.ServiceManager', 'Select a theme for the service.'))
|
2015-11-07 00:49:40 +00:00
|
|
|
self.theme_combo_box.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToMinimumContentsLength)
|
|
|
|
self.theme_combo_box.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
|
2013-08-31 18:17:38 +00:00
|
|
|
self.theme_combo_box.setObjectName('theme_combo_box')
|
2013-03-07 06:48:09 +00:00
|
|
|
self.toolbar.add_toolbar_widget(self.theme_combo_box)
|
2013-08-31 18:17:38 +00:00
|
|
|
self.toolbar.setObjectName('toolbar')
|
2013-02-02 19:49:56 +00:00
|
|
|
self.layout.addWidget(self.toolbar)
|
|
|
|
# Create the service manager list
|
2013-12-31 21:02:35 +00:00
|
|
|
self.service_manager_list = ServiceManagerList(widget)
|
2013-02-02 19:49:56 +00:00
|
|
|
self.service_manager_list.setEditTriggers(
|
2015-11-07 00:49:40 +00:00
|
|
|
QtWidgets.QAbstractItemView.CurrentChanged |
|
|
|
|
QtWidgets.QAbstractItemView.DoubleClicked |
|
|
|
|
QtWidgets.QAbstractItemView.EditKeyPressed)
|
2013-02-02 19:49:56 +00:00
|
|
|
self.service_manager_list.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
|
2013-02-14 21:50:10 +00:00
|
|
|
self.service_manager_list.customContextMenuRequested.connect(self.context_menu)
|
2013-08-31 18:17:38 +00:00
|
|
|
self.service_manager_list.setObjectName('service_manager_list')
|
2013-02-02 19:49:56 +00:00
|
|
|
# enable drop
|
2017-10-23 22:09:57 +00:00
|
|
|
self.service_manager_list.dropEvent = self.drop_event
|
2013-02-02 19:49:56 +00:00
|
|
|
self.layout.addWidget(self.service_manager_list)
|
|
|
|
# Add the bottom toolbar
|
2013-12-31 21:02:35 +00:00
|
|
|
self.order_toolbar = OpenLPToolbar(widget)
|
2013-02-02 19:49:56 +00:00
|
|
|
action_list = ActionList.get_instance()
|
2013-02-19 09:13:49 +00:00
|
|
|
action_list.add_category(UiStrings().Service, CategoryOrder.standard_toolbar)
|
2017-10-23 22:09:57 +00:00
|
|
|
self.move_top_action = self.order_toolbar.add_toolbar_action(
|
2013-12-30 19:50:34 +00:00
|
|
|
'moveTop',
|
2013-08-31 18:17:38 +00:00
|
|
|
text=translate('OpenLP.ServiceManager', 'Move to &top'), icon=':/services/service_top.png',
|
2013-02-02 19:49:56 +00:00
|
|
|
tooltip=translate('OpenLP.ServiceManager', 'Move item to the top of the service.'),
|
2013-12-30 19:50:34 +00:00
|
|
|
can_shortcuts=True, category=UiStrings().Service, triggers=self.on_service_top)
|
2017-10-23 22:09:57 +00:00
|
|
|
self.move_up_action = self.order_toolbar.add_toolbar_action(
|
2013-12-30 19:50:34 +00:00
|
|
|
'moveUp',
|
2013-08-31 18:17:38 +00:00
|
|
|
text=translate('OpenLP.ServiceManager', 'Move &up'), icon=':/services/service_up.png',
|
2013-02-02 19:49:56 +00:00
|
|
|
tooltip=translate('OpenLP.ServiceManager', 'Move item up one position in the service.'),
|
2013-12-30 19:50:34 +00:00
|
|
|
can_shortcuts=True, category=UiStrings().Service, triggers=self.on_service_up)
|
2017-10-23 22:09:57 +00:00
|
|
|
self.move_down_action = self.order_toolbar.add_toolbar_action(
|
2013-12-30 19:50:34 +00:00
|
|
|
'moveDown',
|
2013-08-31 18:17:38 +00:00
|
|
|
text=translate('OpenLP.ServiceManager', 'Move &down'), icon=':/services/service_down.png',
|
2013-02-02 19:49:56 +00:00
|
|
|
tooltip=translate('OpenLP.ServiceManager', 'Move item down one position in the service.'),
|
2013-12-30 19:50:34 +00:00
|
|
|
can_shortcuts=True, category=UiStrings().Service, triggers=self.on_service_down)
|
2017-10-23 22:09:57 +00:00
|
|
|
self.move_bottom_action = self.order_toolbar.add_toolbar_action(
|
2013-12-30 19:50:34 +00:00
|
|
|
'moveBottom',
|
2013-08-31 18:17:38 +00:00
|
|
|
text=translate('OpenLP.ServiceManager', 'Move to &bottom'), icon=':/services/service_bottom.png',
|
2013-02-02 19:49:56 +00:00
|
|
|
tooltip=translate('OpenLP.ServiceManager', 'Move item to the end of the service.'),
|
2013-12-30 19:50:34 +00:00
|
|
|
can_shortcuts=True, category=UiStrings().Service, triggers=self.on_service_end)
|
2013-02-02 19:49:56 +00:00
|
|
|
self.order_toolbar.addSeparator()
|
2017-10-23 22:09:57 +00:00
|
|
|
self.delete_action = self.order_toolbar.add_toolbar_action(
|
2013-12-30 19:50:34 +00:00
|
|
|
'delete', can_shortcuts=True,
|
2013-08-31 18:17:38 +00:00
|
|
|
text=translate('OpenLP.ServiceManager', '&Delete From Service'), icon=':/general/general_delete.png',
|
2013-02-02 19:49:56 +00:00
|
|
|
tooltip=translate('OpenLP.ServiceManager', 'Delete the selected item from the service.'),
|
2013-12-30 19:50:34 +00:00
|
|
|
triggers=self.on_delete_from_service)
|
2013-02-02 19:49:56 +00:00
|
|
|
self.order_toolbar.addSeparator()
|
2017-10-23 22:09:57 +00:00
|
|
|
self.expand_action = self.order_toolbar.add_toolbar_action(
|
2013-12-30 19:50:34 +00:00
|
|
|
'expand', can_shortcuts=True,
|
2013-08-31 18:17:38 +00:00
|
|
|
text=translate('OpenLP.ServiceManager', '&Expand all'), icon=':/services/service_expand_all.png',
|
2013-02-02 19:49:56 +00:00
|
|
|
tooltip=translate('OpenLP.ServiceManager', 'Expand all the service items.'),
|
2013-12-26 08:56:53 +00:00
|
|
|
category=UiStrings().Service, triggers=self.on_expand_all)
|
2017-10-23 22:09:57 +00:00
|
|
|
self.collapse_action = self.order_toolbar.add_toolbar_action(
|
2013-12-30 19:50:34 +00:00
|
|
|
'collapse', can_shortcuts=True,
|
2013-08-31 18:17:38 +00:00
|
|
|
text=translate('OpenLP.ServiceManager', '&Collapse all'), icon=':/services/service_collapse_all.png',
|
2013-02-02 19:49:56 +00:00
|
|
|
tooltip=translate('OpenLP.ServiceManager', 'Collapse all the service items.'),
|
2013-12-26 08:56:53 +00:00
|
|
|
category=UiStrings().Service, triggers=self.on_collapse_all)
|
2013-02-02 19:49:56 +00:00
|
|
|
self.order_toolbar.addSeparator()
|
2017-10-23 22:09:57 +00:00
|
|
|
self.make_live_action = self.order_toolbar.add_toolbar_action(
|
2013-12-30 19:50:34 +00:00
|
|
|
'make_live', can_shortcuts=True,
|
2013-08-31 18:17:38 +00:00
|
|
|
text=translate('OpenLP.ServiceManager', 'Go Live'), icon=':/general/general_live.png',
|
2013-02-02 19:49:56 +00:00
|
|
|
tooltip=translate('OpenLP.ServiceManager', 'Send the selected item to Live.'),
|
2013-02-19 09:13:49 +00:00
|
|
|
category=UiStrings().Service,
|
2017-11-13 21:31:54 +00:00
|
|
|
triggers=self.on_make_live_action_triggered)
|
2013-02-02 19:49:56 +00:00
|
|
|
self.layout.addWidget(self.order_toolbar)
|
|
|
|
# Connect up our signals and slots
|
2013-02-14 21:50:10 +00:00
|
|
|
self.theme_combo_box.activated.connect(self.on_theme_combo_box_selected)
|
2016-01-19 06:52:23 +00:00
|
|
|
self.service_manager_list.doubleClicked.connect(self.on_double_click_live)
|
2016-01-17 16:46:37 +00:00
|
|
|
self.service_manager_list.clicked.connect(self.on_single_click_preview)
|
2013-02-14 21:50:10 +00:00
|
|
|
self.service_manager_list.itemCollapsed.connect(self.collapsed)
|
|
|
|
self.service_manager_list.itemExpanded.connect(self.expanded)
|
2013-02-02 19:49:56 +00:00
|
|
|
# Last little bits of setting up
|
2013-08-31 18:17:38 +00:00
|
|
|
self.service_theme = Settings().value(self.main_window.service_manager_settings_section + '/service theme')
|
2017-08-01 20:59:41 +00:00
|
|
|
self.service_path = str(AppLocation.get_section_data_path('servicemanager'))
|
2013-02-02 19:49:56 +00:00
|
|
|
# build the drag and drop context menu
|
2015-11-07 00:49:40 +00:00
|
|
|
self.dnd_menu = QtWidgets.QMenu()
|
2013-12-26 08:56:53 +00:00
|
|
|
self.new_action = self.dnd_menu.addAction(translate('OpenLP.ServiceManager', '&Add New Item'))
|
|
|
|
self.new_action.setIcon(build_icon(':/general/general_edit.png'))
|
|
|
|
self.add_to_action = self.dnd_menu.addAction(translate('OpenLP.ServiceManager', '&Add to Selected Item'))
|
|
|
|
self.add_to_action.setIcon(build_icon(':/general/general_edit.png'))
|
2013-02-02 19:49:56 +00:00
|
|
|
# build the context menu
|
2015-11-07 00:49:40 +00:00
|
|
|
self.menu = QtWidgets.QMenu()
|
2013-02-02 19:49:56 +00:00
|
|
|
self.edit_action = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', '&Edit Item'),
|
2013-12-26 08:56:53 +00:00
|
|
|
icon=':/general/general_edit.png', triggers=self.remote_edit)
|
2013-04-02 10:19:33 +00:00
|
|
|
self.rename_action = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', '&Rename...'),
|
2014-04-13 07:54:34 +00:00
|
|
|
icon=':/general/general_edit.png',
|
|
|
|
triggers=self.on_service_item_rename)
|
2013-02-02 19:49:56 +00:00
|
|
|
self.maintain_action = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', '&Reorder Item'),
|
2013-12-26 08:56:53 +00:00
|
|
|
icon=':/general/general_edit.png',
|
|
|
|
triggers=self.on_service_item_edit_form)
|
2013-02-02 19:49:56 +00:00
|
|
|
self.notes_action = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', '&Notes'),
|
2013-12-26 08:56:53 +00:00
|
|
|
icon=':/services/service_notes.png',
|
|
|
|
triggers=self.on_service_item_note_form)
|
2013-02-02 19:49:56 +00:00
|
|
|
self.time_action = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', '&Start Time'),
|
2013-12-26 08:56:53 +00:00
|
|
|
icon=':/media/media_time.png', triggers=self.on_start_time_form)
|
2013-08-31 18:17:38 +00:00
|
|
|
self.auto_start_action = create_widget_action(self.menu, text='',
|
2013-12-26 08:56:53 +00:00
|
|
|
icon=':/media/auto-start_active.png',
|
|
|
|
triggers=self.on_auto_start)
|
2013-02-02 19:49:56 +00:00
|
|
|
# Add already existing delete action to the menu.
|
2017-10-23 22:09:57 +00:00
|
|
|
self.menu.addAction(self.delete_action)
|
2013-02-02 19:49:56 +00:00
|
|
|
self.create_custom_action = create_widget_action(self.menu,
|
2013-12-26 08:56:53 +00:00
|
|
|
text=translate('OpenLP.ServiceManager', 'Create New &Custom '
|
|
|
|
'Slide'),
|
|
|
|
icon=':/general/general_edit.png',
|
|
|
|
triggers=self.create_custom)
|
2013-02-02 19:49:56 +00:00
|
|
|
self.menu.addSeparator()
|
|
|
|
# Add AutoPlay menu actions
|
2015-11-07 00:49:40 +00:00
|
|
|
self.auto_play_slides_menu = QtWidgets.QMenu(translate('OpenLP.ServiceManager', '&Auto play slides'))
|
2013-03-30 09:33:21 +00:00
|
|
|
self.menu.addMenu(self.auto_play_slides_menu)
|
2015-11-07 00:49:40 +00:00
|
|
|
auto_play_slides_group = QtWidgets.QActionGroup(self.auto_play_slides_menu)
|
2013-03-30 09:33:21 +00:00
|
|
|
auto_play_slides_group.setExclusive(True)
|
|
|
|
self.auto_play_slides_loop = create_widget_action(self.auto_play_slides_menu,
|
2013-12-26 08:56:53 +00:00
|
|
|
text=translate('OpenLP.ServiceManager', 'Auto play slides '
|
|
|
|
'&Loop'),
|
|
|
|
checked=False, triggers=self.toggle_auto_play_slides_loop)
|
2013-03-30 09:33:21 +00:00
|
|
|
auto_play_slides_group.addAction(self.auto_play_slides_loop)
|
|
|
|
self.auto_play_slides_once = create_widget_action(self.auto_play_slides_menu,
|
2013-12-26 08:56:53 +00:00
|
|
|
text=translate('OpenLP.ServiceManager', 'Auto play slides '
|
|
|
|
'&Once'),
|
|
|
|
checked=False, triggers=self.toggle_auto_play_slides_once)
|
2013-03-30 09:33:21 +00:00
|
|
|
auto_play_slides_group.addAction(self.auto_play_slides_once)
|
|
|
|
self.auto_play_slides_menu.addSeparator()
|
|
|
|
self.timed_slide_interval = create_widget_action(self.auto_play_slides_menu,
|
2013-12-26 08:56:53 +00:00
|
|
|
text=translate('OpenLP.ServiceManager', '&Delay between '
|
|
|
|
'slides'),
|
|
|
|
triggers=self.on_timed_slide_interval)
|
2013-02-02 19:49:56 +00:00
|
|
|
self.menu.addSeparator()
|
|
|
|
self.preview_action = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', 'Show &Preview'),
|
2013-12-26 08:56:53 +00:00
|
|
|
icon=':/general/general_preview.png', triggers=self.make_preview)
|
2013-02-02 19:49:56 +00:00
|
|
|
# Add already existing make live action to the menu.
|
2017-10-23 22:09:57 +00:00
|
|
|
self.menu.addAction(self.make_live_action)
|
2013-02-02 19:49:56 +00:00
|
|
|
self.menu.addSeparator()
|
2015-11-07 00:49:40 +00:00
|
|
|
self.theme_menu = QtWidgets.QMenu(translate('OpenLP.ServiceManager', '&Change Item Theme'))
|
2013-02-02 19:49:56 +00:00
|
|
|
self.menu.addMenu(self.theme_menu)
|
2017-10-23 22:09:57 +00:00
|
|
|
self.service_manager_list.addActions([self.move_down_action, self.move_up_action, self.make_live_action,
|
2017-11-09 19:11:37 +00:00
|
|
|
self.move_top_action, self.move_bottom_action, self.expand_action,
|
|
|
|
self.collapse_action])
|
2013-08-31 18:17:38 +00:00
|
|
|
Registry().register_function('theme_update_list', self.update_theme_list)
|
2013-12-26 08:56:53 +00:00
|
|
|
Registry().register_function('config_screen_changed', self.regenerate_service_items)
|
2013-08-31 18:17:38 +00:00
|
|
|
Registry().register_function('theme_update_global', self.theme_change)
|
|
|
|
Registry().register_function('mediaitem_suffix_reset', self.reset_supported_suffixes)
|
2013-02-02 19:49:56 +00:00
|
|
|
|
2013-01-27 07:36:04 +00:00
|
|
|
|
2017-10-23 22:09:57 +00:00
|
|
|
class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixin, RegistryProperties):
|
2013-01-27 07:36:04 +00:00
|
|
|
"""
|
2013-03-29 12:53:07 +00:00
|
|
|
Manages the services. This involves taking text strings from plugins and adding them to the service. This service
|
|
|
|
can then be zipped up with all the resources used into one OSZ or oszl file for use on any OpenLP v2 installation.
|
|
|
|
Also handles the UI tasks of moving things up and down etc.
|
2013-01-27 07:36:04 +00:00
|
|
|
"""
|
2015-11-07 00:49:40 +00:00
|
|
|
servicemanager_set_item = QtCore.pyqtSignal(int)
|
|
|
|
servicemanager_next_item = QtCore.pyqtSignal()
|
|
|
|
servicemanager_previous_item = QtCore.pyqtSignal()
|
|
|
|
|
2013-01-27 07:36:04 +00:00
|
|
|
def __init__(self, parent=None):
|
|
|
|
"""
|
|
|
|
Sets up the service manager, toolbars, list view, et al.
|
|
|
|
"""
|
2017-10-23 22:09:57 +00:00
|
|
|
super().__init__(parent)
|
2013-08-31 18:17:38 +00:00
|
|
|
self.active = build_icon(':/media/auto-start_active.png')
|
|
|
|
self.inactive = build_icon(':/media/auto-start_inactive.png')
|
2013-01-27 07:36:04 +00:00
|
|
|
self.service_items = []
|
|
|
|
self.suffixes = []
|
2014-10-29 21:04:17 +00:00
|
|
|
self.drop_position = -1
|
2013-01-27 07:36:04 +00:00
|
|
|
self.service_id = 0
|
|
|
|
# is a new service and has not been saved
|
|
|
|
self._modified = False
|
2017-11-18 23:14:28 +00:00
|
|
|
self._service_path = None
|
2013-01-27 07:36:04 +00:00
|
|
|
self.service_has_all_original_files = True
|
2016-01-19 06:52:23 +00:00
|
|
|
self.list_double_clicked = False
|
2013-12-30 19:50:34 +00:00
|
|
|
|
|
|
|
def bootstrap_initialise(self):
|
2014-01-01 09:33:07 +00:00
|
|
|
"""
|
|
|
|
To be called as part of initialisation
|
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
self.setup_ui(self)
|
2013-03-17 21:20:40 +00:00
|
|
|
# Need to use event as called across threads and UI is updated
|
2015-11-07 00:49:40 +00:00
|
|
|
self.servicemanager_set_item.connect(self.on_set_item)
|
|
|
|
self.servicemanager_next_item.connect(self.next_item)
|
|
|
|
self.servicemanager_previous_item.connect(self.previous_item)
|
2013-01-27 07:36:04 +00:00
|
|
|
|
2013-12-30 19:50:34 +00:00
|
|
|
def bootstrap_post_set_up(self):
|
|
|
|
"""
|
|
|
|
Can be set up as a late setup
|
|
|
|
"""
|
|
|
|
self.service_note_form = ServiceNoteForm()
|
|
|
|
self.service_item_edit_form = ServiceItemEditForm()
|
|
|
|
self.start_time_form = StartTimeForm()
|
|
|
|
|
2013-01-27 07:36:04 +00:00
|
|
|
def set_modified(self, modified=True):
|
2010-12-31 21:43:02 +00:00
|
|
|
"""
|
2013-03-29 12:53:07 +00:00
|
|
|
Setter for property "modified". Sets whether or not the current service has been modified.
|
2014-01-01 09:33:07 +00:00
|
|
|
|
|
|
|
:param modified: Indicates if the service has new or removed items. Used to trigger a remote update.
|
2010-12-31 21:43:02 +00:00
|
|
|
"""
|
2012-04-10 19:38:25 +00:00
|
|
|
if modified:
|
2013-01-21 07:29:43 +00:00
|
|
|
self.service_id += 1
|
2010-12-31 21:43:02 +00:00
|
|
|
self._modified = modified
|
2017-11-22 21:39:40 +00:00
|
|
|
if self._service_path:
|
|
|
|
service_file = self._service_path.name
|
|
|
|
else:
|
|
|
|
service_file = translate('OpenLP.ServiceManager', 'Untitled Service')
|
2013-03-16 11:05:52 +00:00
|
|
|
self.main_window.set_service_modified(modified, service_file)
|
2010-12-31 21:43:02 +00:00
|
|
|
|
2013-01-27 07:36:04 +00:00
|
|
|
def is_modified(self):
|
2010-12-31 21:43:02 +00:00
|
|
|
"""
|
|
|
|
Getter for boolean property "modified".
|
|
|
|
"""
|
|
|
|
return self._modified
|
|
|
|
|
2017-09-06 21:36:31 +00:00
|
|
|
def set_file_name(self, file_path):
|
2010-12-31 21:43:02 +00:00
|
|
|
"""
|
|
|
|
Setter for service file.
|
2014-01-01 09:57:06 +00:00
|
|
|
|
2017-09-06 21:36:31 +00:00
|
|
|
:param openlp.core.common.path.Path file_path: The service file name
|
|
|
|
:rtype: None
|
2010-12-31 21:43:02 +00:00
|
|
|
"""
|
2017-11-18 23:14:28 +00:00
|
|
|
self._service_path = file_path
|
2017-12-09 08:22:14 +00:00
|
|
|
self.set_modified(self.is_modified())
|
2017-09-06 21:36:31 +00:00
|
|
|
Settings().setValue('servicemanager/last file', file_path)
|
2017-09-23 13:06:42 +00:00
|
|
|
if file_path and file_path.suffix == '.oszl':
|
2017-09-18 06:20:06 +00:00
|
|
|
self._save_lite = True
|
|
|
|
else:
|
|
|
|
self._save_lite = False
|
2010-12-31 21:43:02 +00:00
|
|
|
|
2013-01-27 07:36:04 +00:00
|
|
|
def file_name(self):
|
2010-12-31 21:43:02 +00:00
|
|
|
"""
|
|
|
|
Return the current file name including path.
|
2017-11-18 23:14:28 +00:00
|
|
|
|
|
|
|
:rtype: openlp.core.common.path.Path
|
2010-12-31 21:43:02 +00:00
|
|
|
"""
|
2017-11-18 23:14:28 +00:00
|
|
|
return self._service_path
|
2010-12-31 21:43:02 +00:00
|
|
|
|
2013-01-27 07:36:04 +00:00
|
|
|
def short_file_name(self):
|
2010-12-31 21:43:02 +00:00
|
|
|
"""
|
|
|
|
Return the current file name, excluding the path.
|
|
|
|
"""
|
2017-12-02 21:47:11 +00:00
|
|
|
if self._service_path:
|
|
|
|
return self._service_path.name
|
2010-12-31 21:43:02 +00:00
|
|
|
|
2013-01-27 07:36:04 +00:00
|
|
|
def reset_supported_suffixes(self):
|
2012-10-07 07:25:55 +00:00
|
|
|
"""
|
2012-11-26 17:57:36 +00:00
|
|
|
Resets the Suffixes list.
|
2012-10-07 07:25:55 +00:00
|
|
|
|
|
|
|
"""
|
|
|
|
self.suffixes = []
|
|
|
|
|
2013-12-31 20:29:03 +00:00
|
|
|
def supported_suffixes(self, suffix_list):
|
2012-08-24 20:06:56 +00:00
|
|
|
"""
|
2013-03-29 12:53:07 +00:00
|
|
|
Adds Suffixes supported to the master list. Called from Plugins.
|
2012-08-24 20:06:56 +00:00
|
|
|
|
2014-01-01 09:33:07 +00:00
|
|
|
:param suffix_list: New Suffix's to be supported
|
2012-08-24 20:06:56 +00:00
|
|
|
"""
|
2014-06-05 16:25:37 +00:00
|
|
|
if isinstance(suffix_list, str):
|
|
|
|
self.suffixes.append(suffix_list)
|
|
|
|
else:
|
|
|
|
for suffix in suffix_list:
|
|
|
|
if suffix not in self.suffixes:
|
|
|
|
self.suffixes.append(suffix)
|
2010-05-05 19:14:48 +00:00
|
|
|
|
2013-12-31 07:27:07 +00:00
|
|
|
def on_new_service_clicked(self, field=None):
|
2010-12-31 21:43:02 +00:00
|
|
|
"""
|
|
|
|
Create a new service.
|
2014-01-01 09:33:07 +00:00
|
|
|
:param field:
|
2010-12-31 21:43:02 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
if self.is_modified():
|
|
|
|
result = self.save_modified_service()
|
2015-11-07 00:49:40 +00:00
|
|
|
if result == QtWidgets.QMessageBox.Cancel:
|
2010-12-31 21:43:02 +00:00
|
|
|
return False
|
2015-11-07 00:49:40 +00:00
|
|
|
elif result == QtWidgets.QMessageBox.Save:
|
2013-01-27 07:36:04 +00:00
|
|
|
if not self.decide_save_method():
|
2010-12-31 21:43:02 +00:00
|
|
|
return False
|
2013-01-27 07:36:04 +00:00
|
|
|
self.new_file()
|
2010-12-31 21:43:02 +00:00
|
|
|
|
2013-01-27 07:36:04 +00:00
|
|
|
def on_load_service_clicked(self, load_file=None):
|
2011-08-02 18:17:07 +00:00
|
|
|
"""
|
2013-03-29 12:53:07 +00:00
|
|
|
Loads the service file and saves the existing one it there is one unchanged.
|
2011-08-02 18:17:07 +00:00
|
|
|
|
2014-01-01 09:33:07 +00:00
|
|
|
:param load_file: The service file to the loaded. Will be None is from menu so selection will be required.
|
2011-08-02 18:17:07 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
if self.is_modified():
|
|
|
|
result = self.save_modified_service()
|
2015-11-07 00:49:40 +00:00
|
|
|
if result == QtWidgets.QMessageBox.Cancel:
|
2010-12-31 21:43:02 +00:00
|
|
|
return False
|
2015-11-07 00:49:40 +00:00
|
|
|
elif result == QtWidgets.QMessageBox.Save:
|
2013-01-27 07:36:04 +00:00
|
|
|
self.decide_save_method()
|
|
|
|
if not load_file:
|
2017-08-26 15:06:11 +00:00
|
|
|
file_path, filter_used = FileDialog.getOpenFileName(
|
2013-02-03 14:40:48 +00:00
|
|
|
self.main_window,
|
2011-08-02 18:17:07 +00:00
|
|
|
translate('OpenLP.ServiceManager', 'Open File'),
|
2013-08-31 18:17:38 +00:00
|
|
|
Settings().value(self.main_window.service_manager_settings_section + '/last directory'),
|
2015-11-07 00:49:40 +00:00
|
|
|
translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz *.oszl)'))
|
2017-08-26 15:06:11 +00:00
|
|
|
if not file_path:
|
2011-08-02 18:17:07 +00:00
|
|
|
return False
|
|
|
|
else:
|
2017-08-26 15:06:11 +00:00
|
|
|
file_path = str_to_path(load_file)
|
|
|
|
Settings().setValue(self.main_window.service_manager_settings_section + '/last directory', file_path.parent)
|
2018-01-06 09:55:19 +00:00
|
|
|
self.load_file(file_path)
|
2010-12-31 21:43:02 +00:00
|
|
|
|
2013-01-27 07:36:04 +00:00
|
|
|
def save_modified_service(self):
|
2013-01-21 11:11:47 +00:00
|
|
|
"""
|
|
|
|
Check to see if a service needs to be saved.
|
|
|
|
"""
|
2015-11-07 00:49:40 +00:00
|
|
|
return QtWidgets.QMessageBox.question(self.main_window,
|
|
|
|
translate('OpenLP.ServiceManager', 'Modified Service'),
|
|
|
|
translate('OpenLP.ServiceManager',
|
|
|
|
'The current service has been modified. Would you like to save '
|
|
|
|
'this service?'),
|
|
|
|
QtWidgets.QMessageBox.Save | QtWidgets.QMessageBox.Discard |
|
|
|
|
QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Save)
|
2010-12-31 21:43:02 +00:00
|
|
|
|
2013-12-30 19:50:34 +00:00
|
|
|
def on_recent_service_clicked(self, field=None):
|
2013-01-21 11:11:47 +00:00
|
|
|
"""
|
|
|
|
Load a recent file as the service triggered by mainwindow recent service list.
|
2014-01-01 09:33:07 +00:00
|
|
|
:param field:
|
2013-01-21 11:11:47 +00:00
|
|
|
"""
|
2017-10-08 19:01:09 +00:00
|
|
|
if self.is_modified():
|
|
|
|
result = self.save_modified_service()
|
|
|
|
if result == QtWidgets.QMessageBox.Cancel:
|
|
|
|
return False
|
|
|
|
elif result == QtWidgets.QMessageBox.Save:
|
|
|
|
self.decide_save_method()
|
2011-01-01 12:25:12 +00:00
|
|
|
sender = self.sender()
|
2018-01-06 09:55:19 +00:00
|
|
|
self.load_file(Path(sender.data()))
|
2011-01-01 12:25:12 +00:00
|
|
|
|
2013-01-27 07:36:04 +00:00
|
|
|
def new_file(self):
|
2011-01-01 12:25:12 +00:00
|
|
|
"""
|
|
|
|
Create a blank new service file.
|
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
self.service_manager_list.clear()
|
|
|
|
self.service_items = []
|
2017-09-06 21:36:31 +00:00
|
|
|
self.set_file_name(None)
|
2013-01-21 07:29:43 +00:00
|
|
|
self.service_id += 1
|
2013-01-27 07:36:04 +00:00
|
|
|
self.set_modified(False)
|
2017-08-26 15:06:11 +00:00
|
|
|
Settings().setValue('servicemanager/last file', None)
|
2013-02-03 09:07:31 +00:00
|
|
|
self.plugin_manager.new_service_created()
|
2011-01-01 12:25:12 +00:00
|
|
|
|
2014-01-04 16:33:20 +00:00
|
|
|
def create_basic_service(self):
|
|
|
|
"""
|
|
|
|
Create the initial service array with the base items to be saved.
|
|
|
|
|
2015-09-08 19:13:59 +00:00
|
|
|
:return: service array
|
2014-01-04 16:33:20 +00:00
|
|
|
"""
|
|
|
|
service = []
|
2016-07-16 22:20:56 +00:00
|
|
|
core = {
|
|
|
|
'lite-service': self._save_lite,
|
|
|
|
'service-theme': self.service_theme
|
|
|
|
}
|
2014-01-04 16:33:20 +00:00
|
|
|
service.append({'openlp_core': core})
|
|
|
|
return service
|
|
|
|
|
2017-12-27 16:06:36 +00:00
|
|
|
def get_write_file_list(self):
|
2018-01-14 09:01:00 +00:00
|
|
|
"""
|
2018-01-20 09:30:30 +00:00
|
|
|
Get a list of files used in the service and files that are missing.
|
2018-01-14 09:01:00 +00:00
|
|
|
|
2018-01-20 09:30:30 +00:00
|
|
|
:return: A list of files used in the service that exist, and a list of files that don't.
|
2018-01-14 09:01:00 +00:00
|
|
|
:rtype: (list[openlp.core.common.path.Path], list[openlp.core.common.path.Path])
|
|
|
|
"""
|
2011-03-09 07:17:58 +00:00
|
|
|
write_list = []
|
2012-10-27 09:06:33 +00:00
|
|
|
missing_list = []
|
2013-01-27 07:36:04 +00:00
|
|
|
for item in self.service_items:
|
2018-01-06 09:55:19 +00:00
|
|
|
if item['service_item'].uses_file():
|
|
|
|
for frame in item['service_item'].get_frames():
|
|
|
|
path_from = item['service_item'].get_frame_path(frame=frame)
|
|
|
|
if path_from in write_list or path_from in missing_list:
|
|
|
|
continue
|
|
|
|
if not os.path.exists(path_from):
|
|
|
|
missing_list.append(Path(path_from))
|
|
|
|
else:
|
|
|
|
write_list.append(Path(path_from))
|
|
|
|
for audio_path in item['service_item'].background_audio:
|
|
|
|
if audio_path in write_list:
|
2011-03-09 07:17:58 +00:00
|
|
|
continue
|
2018-01-06 09:55:19 +00:00
|
|
|
write_list.append(audio_path)
|
2017-12-27 16:06:36 +00:00
|
|
|
return write_list, missing_list
|
|
|
|
|
|
|
|
def save_file(self):
|
|
|
|
"""
|
|
|
|
Save the current service file.
|
|
|
|
|
|
|
|
A temporary file is created so that we don't overwrite the existing one and leave a mangled service file should
|
|
|
|
there be an error when saving. Audio files are also copied into the service manager directory, and then packaged
|
|
|
|
into the zip file.
|
|
|
|
"""
|
|
|
|
file_path = self.file_name()
|
|
|
|
self.log_debug('ServiceManager.save_file - {name}'.format(name=file_path))
|
|
|
|
self.application.set_busy_cursor()
|
2017-12-30 08:08:10 +00:00
|
|
|
|
|
|
|
service = self.create_basic_service()
|
|
|
|
|
2018-01-06 09:55:19 +00:00
|
|
|
write_list = []
|
|
|
|
missing_list = []
|
2017-12-30 08:08:10 +00:00
|
|
|
|
2018-01-06 09:55:19 +00:00
|
|
|
if not self._save_lite:
|
|
|
|
write_list, missing_list = self.get_write_file_list()
|
|
|
|
|
|
|
|
if missing_list:
|
|
|
|
self.application.set_normal_cursor()
|
|
|
|
title = translate('OpenLP.ServiceManager', 'Service File(s) Missing')
|
|
|
|
message = translate('OpenLP.ServiceManager',
|
|
|
|
'The following file(s) in the service are missing: {name}\n\n'
|
|
|
|
'These files will be removed if you continue to save.'
|
|
|
|
).format(name='\n\t'.join(missing_list))
|
|
|
|
answer = QtWidgets.QMessageBox.critical(self, title, message,
|
|
|
|
QtWidgets.QMessageBox.StandardButtons(
|
|
|
|
QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel))
|
|
|
|
if answer == QtWidgets.QMessageBox.Cancel:
|
|
|
|
return False
|
2012-10-27 09:06:33 +00:00
|
|
|
# Check if item contains a missing file.
|
2013-01-27 07:36:04 +00:00
|
|
|
for item in list(self.service_items):
|
2018-01-06 09:55:19 +00:00
|
|
|
if not self._save_lite:
|
|
|
|
item['service_item'].remove_invalid_frames(missing_list)
|
|
|
|
if item['service_item'].missing_frames():
|
|
|
|
self.service_items.remove(item)
|
|
|
|
continue
|
2017-12-30 08:08:10 +00:00
|
|
|
service_item = item['service_item'].get_service_repr(self._save_lite)
|
|
|
|
# Add the service item to the service.
|
|
|
|
service.append({'serviceitem': service_item})
|
2013-01-27 20:36:18 +00:00
|
|
|
self.repaint_service_list(-1, -1)
|
2017-12-30 08:08:10 +00:00
|
|
|
service_content = json.dumps(service, cls=OpenLPJsonEncoder)
|
2018-01-13 09:02:29 +00:00
|
|
|
service_content_size = len(bytes(service_content, encoding='utf-8'))
|
|
|
|
total_size = service_content_size
|
2013-01-21 07:29:43 +00:00
|
|
|
for file_item in write_list:
|
2018-01-13 09:02:29 +00:00
|
|
|
total_size += file_item.stat().st_size
|
2013-12-31 20:29:03 +00:00
|
|
|
self.log_debug('ServiceManager.save_file - ZIP contents size is %i bytes' % total_size)
|
2017-12-30 08:08:10 +00:00
|
|
|
self.main_window.display_progress_bar(total_size)
|
2011-03-09 07:17:58 +00:00
|
|
|
try:
|
2017-12-27 16:06:36 +00:00
|
|
|
with NamedTemporaryFile() as temp_file, \
|
|
|
|
zipfile.ZipFile(temp_file, 'w') as zip_file:
|
|
|
|
# First we add service contents..
|
2018-01-06 09:55:19 +00:00
|
|
|
zip_file.writestr('service_data.osj', service_content)
|
2018-01-13 09:02:29 +00:00
|
|
|
self.main_window.increment_progress_bar(service_content_size)
|
2017-12-27 16:06:36 +00:00
|
|
|
# Finally add all the listed media files.
|
2018-01-13 09:02:29 +00:00
|
|
|
for write_path in write_list:
|
|
|
|
zip_file.write(str(write_path), str(write_path))
|
|
|
|
self.main_window.increment_progress_bar(write_path.stat().st_size)
|
2017-12-30 08:08:10 +00:00
|
|
|
with suppress(FileNotFoundError):
|
|
|
|
file_path.unlink()
|
2018-01-13 07:24:20 +00:00
|
|
|
os.link(temp_file.name, str(file_path))
|
2017-12-30 08:08:10 +00:00
|
|
|
Settings().setValue(self.main_window.service_manager_settings_section + '/last directory', file_path.parent)
|
2017-12-27 16:06:36 +00:00
|
|
|
except (PermissionError, OSError) as error:
|
|
|
|
self.log_exception('Failed to save service to disk: {name}'.format(name=temp_file.name))
|
|
|
|
self.main_window.error_message(
|
|
|
|
translate('OpenLP.ServiceManager', 'Error Saving File'),
|
|
|
|
translate('OpenLP.ServiceManager', 'There was an error saving your file.\n\n{error}').format(error=error))
|
|
|
|
return self.save_file_as()
|
2013-03-16 11:05:52 +00:00
|
|
|
self.main_window.finished_progress_bar()
|
2013-02-03 19:23:12 +00:00
|
|
|
self.application.set_normal_cursor()
|
2017-12-27 16:06:36 +00:00
|
|
|
self.main_window.add_recent_file(file_path)
|
|
|
|
self.set_modified(False)
|
|
|
|
return True
|
2010-12-31 21:43:02 +00:00
|
|
|
|
2014-01-04 16:33:20 +00:00
|
|
|
def save_file_as(self, field=None):
|
2010-12-31 21:43:02 +00:00
|
|
|
"""
|
2013-03-29 12:53:07 +00:00
|
|
|
Get a file name and then call :func:`ServiceManager.save_file` to save the file.
|
2010-12-31 21:43:02 +00:00
|
|
|
"""
|
2013-08-31 18:17:38 +00:00
|
|
|
default_service_enabled = Settings().value('advanced/default service enabled')
|
2012-01-25 09:32:20 +00:00
|
|
|
if default_service_enabled:
|
2013-08-31 18:17:38 +00:00
|
|
|
service_day = Settings().value('advanced/default service day')
|
2012-01-25 09:32:20 +00:00
|
|
|
if service_day == 7:
|
2012-09-16 15:33:05 +00:00
|
|
|
local_time = datetime.now()
|
2012-01-25 09:32:20 +00:00
|
|
|
else:
|
2013-08-31 18:17:38 +00:00
|
|
|
service_hour = Settings().value('advanced/default service hour')
|
|
|
|
service_minute = Settings().value('advanced/default service minute')
|
2012-01-25 09:32:20 +00:00
|
|
|
now = datetime.now()
|
|
|
|
day_delta = service_day - now.weekday()
|
|
|
|
if day_delta < 0:
|
|
|
|
day_delta += 7
|
|
|
|
time = now + timedelta(days=day_delta)
|
2012-09-16 15:33:05 +00:00
|
|
|
local_time = time.replace(hour=service_hour, minute=service_minute)
|
2013-08-31 18:17:38 +00:00
|
|
|
default_pattern = Settings().value('advanced/default service name')
|
2013-01-27 07:36:04 +00:00
|
|
|
default_file_name = format_time(default_pattern, local_time)
|
2012-01-15 01:21:35 +00:00
|
|
|
else:
|
2013-08-31 18:17:38 +00:00
|
|
|
default_file_name = ''
|
2017-09-23 13:06:42 +00:00
|
|
|
default_file_path = Path(default_file_name)
|
2017-09-06 21:36:31 +00:00
|
|
|
directory_path = Settings().value(self.main_window.service_manager_settings_section + '/last directory')
|
2017-09-23 13:06:42 +00:00
|
|
|
if directory_path:
|
|
|
|
default_file_path = directory_path / default_file_path
|
2017-10-08 19:29:54 +00:00
|
|
|
lite_filter = translate('OpenLP.ServiceManager', 'OpenLP Service Files - lite (*.oszl)')
|
|
|
|
packaged_filter = translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)')
|
2017-11-18 23:14:28 +00:00
|
|
|
if self._service_path and self._service_path.suffix == '.oszl':
|
2017-11-14 22:13:38 +00:00
|
|
|
default_filter = lite_filter
|
|
|
|
else:
|
|
|
|
default_filter = packaged_filter
|
|
|
|
# SaveAs from osz to oszl is not valid as the files will be deleted on exit which is not sensible or usable in
|
|
|
|
# the long term.
|
2017-11-18 23:14:28 +00:00
|
|
|
if self._service_path and self._service_path.suffix == '.oszl' or self.service_has_all_original_files:
|
2017-09-06 21:36:31 +00:00
|
|
|
file_path, filter_used = FileDialog.getSaveFileName(
|
2017-09-23 13:06:42 +00:00
|
|
|
self.main_window, UiStrings().SaveService, default_file_path,
|
2017-11-14 22:13:38 +00:00
|
|
|
'{packaged};; {lite}'.format(packaged=packaged_filter, lite=lite_filter),
|
|
|
|
default_filter)
|
2012-11-01 16:36:45 +00:00
|
|
|
else:
|
2017-09-06 21:36:31 +00:00
|
|
|
file_path, filter_used = FileDialog.getSaveFileName(
|
2017-10-08 19:29:54 +00:00
|
|
|
self.main_window, UiStrings().SaveService, default_file_path,
|
|
|
|
'{packaged};;'.format(packaged=packaged_filter))
|
2017-09-06 21:36:31 +00:00
|
|
|
if not file_path:
|
2010-12-31 21:43:02 +00:00
|
|
|
return False
|
2017-10-08 19:29:54 +00:00
|
|
|
if filter_used == lite_filter:
|
|
|
|
file_path = file_path.with_suffix('.oszl')
|
|
|
|
else:
|
|
|
|
file_path = file_path.with_suffix('.osz')
|
2017-09-06 21:36:31 +00:00
|
|
|
self.set_file_name(file_path)
|
2013-01-27 07:36:04 +00:00
|
|
|
self.decide_save_method()
|
2012-10-14 15:58:04 +00:00
|
|
|
|
2013-12-31 20:29:03 +00:00
|
|
|
def decide_save_method(self, field=None):
|
2012-10-14 15:58:04 +00:00
|
|
|
"""
|
|
|
|
Determine which type of save method to use.
|
2014-01-01 09:33:07 +00:00
|
|
|
:param field:
|
2012-10-14 15:58:04 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
if not self.file_name():
|
|
|
|
return self.save_file_as()
|
2018-01-06 09:55:19 +00:00
|
|
|
return self.save_file()
|
2010-12-31 21:43:02 +00:00
|
|
|
|
2018-01-06 09:55:19 +00:00
|
|
|
def load_file(self, file_path):
|
2012-10-14 15:58:04 +00:00
|
|
|
"""
|
|
|
|
Load an existing service file
|
2018-01-06 09:55:19 +00:00
|
|
|
:param file_path:
|
2012-10-14 15:58:04 +00:00
|
|
|
"""
|
2018-01-06 09:55:19 +00:00
|
|
|
if not file_path.exists():
|
2010-12-31 21:43:02 +00:00
|
|
|
return False
|
2018-01-06 09:55:19 +00:00
|
|
|
service_data = None
|
2013-02-03 19:23:12 +00:00
|
|
|
self.application.set_busy_cursor()
|
2010-12-31 21:43:02 +00:00
|
|
|
try:
|
2018-01-06 09:55:19 +00:00
|
|
|
with zipfile.ZipFile(str(file_path)) as zip_file:
|
2018-01-13 09:02:29 +00:00
|
|
|
compressed_size = 0
|
|
|
|
for zip_info in zip_file.infolist():
|
|
|
|
compressed_size += zip_info.compress_size
|
|
|
|
self.main_window.display_progress_bar(compressed_size)
|
2018-01-06 09:55:19 +00:00
|
|
|
for zip_info in zip_file.infolist():
|
|
|
|
self.log_debug('Extract file: {name}'.format(name=zip_info.filename))
|
|
|
|
# The json file has been called 'service_data.osj' since OpenLP 3.0
|
|
|
|
if zip_info.filename == 'service_data.osj' or zip_info.filename.endswith('osj'):
|
|
|
|
with zip_file.open(zip_info, 'r') as json_file:
|
|
|
|
service_data = json_file.read()
|
|
|
|
else:
|
|
|
|
zip_info.filename = os.path.basename(zip_info.filename)
|
|
|
|
zip_file.extract(zip_info, str(self.service_path))
|
2018-01-13 09:02:29 +00:00
|
|
|
self.main_window.increment_progress_bar(zip_info.compress_size)
|
2018-01-06 09:55:19 +00:00
|
|
|
if service_data:
|
|
|
|
items = json.loads(service_data, cls=OpenLPJsonDecoder)
|
2013-01-27 07:36:04 +00:00
|
|
|
self.new_file()
|
2014-01-04 16:33:20 +00:00
|
|
|
self.process_service_items(items)
|
2018-01-06 09:55:19 +00:00
|
|
|
self.set_file_name(file_path)
|
|
|
|
self.main_window.add_recent_file(file_path)
|
2013-01-27 07:36:04 +00:00
|
|
|
self.set_modified(False)
|
2018-01-06 09:55:19 +00:00
|
|
|
Settings().setValue('servicemanager/last file', file_path)
|
2011-03-16 07:55:08 +00:00
|
|
|
else:
|
2018-01-06 09:55:19 +00:00
|
|
|
raise ValidationError(msg='No service data found')
|
|
|
|
except (NameError, OSError, ValidationError, zipfile.BadZipFile) as e:
|
|
|
|
self.log_exception('Problem loading service file {name}'.format(name=file_path))
|
|
|
|
critical_error_message_box(
|
|
|
|
message=translate('OpenLP.ServiceManager',
|
|
|
|
'The service file {file_path} could not be loaded because it is either corrupt, or '
|
|
|
|
'not a valid OpenLP 2 or OpenLP 3 service file.'.format(file_path=file_path)))
|
2013-03-16 11:05:52 +00:00
|
|
|
self.main_window.finished_progress_bar()
|
2013-02-03 19:23:12 +00:00
|
|
|
self.application.set_normal_cursor()
|
2013-01-27 20:36:18 +00:00
|
|
|
self.repaint_service_list(-1, -1)
|
2010-12-31 21:43:02 +00:00
|
|
|
|
2014-01-04 16:33:20 +00:00
|
|
|
def process_service_items(self, service_items):
|
|
|
|
"""
|
|
|
|
Process all the array of service items loaded from the saved service
|
|
|
|
|
|
|
|
:param service_items: list of service_items
|
|
|
|
"""
|
|
|
|
for item in service_items:
|
|
|
|
self.main_window.increment_progress_bar()
|
|
|
|
service_item = ServiceItem()
|
|
|
|
if 'openlp_core' in item:
|
2018-01-06 09:55:19 +00:00
|
|
|
item = item['openlp_core']
|
|
|
|
self._save_lite = item.get('lite-service', False)
|
2014-01-04 16:33:20 +00:00
|
|
|
theme = item.get('service-theme', None)
|
|
|
|
if theme:
|
|
|
|
find_and_set_in_combo_box(self.theme_combo_box, theme, set_missing=False)
|
|
|
|
if theme == self.theme_combo_box.currentText():
|
|
|
|
self.renderer.set_service_theme(theme)
|
|
|
|
else:
|
|
|
|
if self._save_lite:
|
|
|
|
service_item.set_from_service(item)
|
|
|
|
else:
|
|
|
|
service_item.set_from_service(item, self.service_path)
|
|
|
|
service_item.validate_item(self.suffixes)
|
|
|
|
if service_item.is_capable(ItemCapabilities.OnLoadUpdate):
|
|
|
|
new_item = Registry().get(service_item.name).service_load(service_item)
|
|
|
|
if new_item:
|
|
|
|
service_item = new_item
|
|
|
|
self.add_service_item(service_item, repaint=False)
|
|
|
|
|
2013-12-26 08:56:53 +00:00
|
|
|
def load_last_file(self):
|
2011-01-02 13:57:55 +00:00
|
|
|
"""
|
2013-03-29 12:53:07 +00:00
|
|
|
Load the last service item from the service manager when the service was last closed. Can be blank if there was
|
|
|
|
no service present.
|
2011-01-02 13:57:55 +00:00
|
|
|
"""
|
2018-01-06 09:55:19 +00:00
|
|
|
file_path = Settings().value('servicemanager/last file')
|
|
|
|
if file_path:
|
|
|
|
self.load_file(file_path)
|
2010-12-31 21:43:02 +00:00
|
|
|
|
2013-01-27 07:36:04 +00:00
|
|
|
def context_menu(self, point):
|
2013-01-21 11:11:47 +00:00
|
|
|
"""
|
|
|
|
The Right click context menu from the Serviceitem list
|
2014-01-01 09:33:07 +00:00
|
|
|
|
|
|
|
:param point: The location of the cursor.
|
2013-01-21 11:11:47 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
item = self.service_manager_list.itemAt(point)
|
2010-03-12 19:39:15 +00:00
|
|
|
if item is None:
|
|
|
|
return
|
2012-05-17 20:06:23 +00:00
|
|
|
if item.parent():
|
2012-05-19 09:13:32 +00:00
|
|
|
pos = item.parent().data(0, QtCore.Qt.UserRole)
|
2010-03-05 09:24:42 +00:00
|
|
|
else:
|
2012-05-19 09:13:32 +00:00
|
|
|
pos = item.data(0, QtCore.Qt.UserRole)
|
2013-01-27 07:36:04 +00:00
|
|
|
service_item = self.service_items[pos - 1]
|
2013-01-27 10:18:06 +00:00
|
|
|
self.edit_action.setVisible(False)
|
2013-04-02 19:28:56 +00:00
|
|
|
self.rename_action.setVisible(False)
|
2012-12-23 00:00:24 +00:00
|
|
|
self.create_custom_action.setVisible(False)
|
2013-01-27 10:18:06 +00:00
|
|
|
self.maintain_action.setVisible(False)
|
|
|
|
self.notes_action.setVisible(False)
|
|
|
|
self.time_action.setVisible(False)
|
|
|
|
self.auto_start_action.setVisible(False)
|
2013-08-31 18:17:38 +00:00
|
|
|
if service_item['service_item'].is_capable(ItemCapabilities.CanEdit) and service_item['service_item'].edit_id:
|
2013-01-27 10:18:06 +00:00
|
|
|
self.edit_action.setVisible(True)
|
2013-09-05 07:23:59 +00:00
|
|
|
if service_item['service_item'].is_capable(ItemCapabilities.CanEditTitle):
|
2013-04-02 19:28:56 +00:00
|
|
|
self.rename_action.setVisible(True)
|
2013-08-31 18:17:38 +00:00
|
|
|
if service_item['service_item'].is_capable(ItemCapabilities.CanMaintain):
|
2013-01-27 10:18:06 +00:00
|
|
|
self.maintain_action.setVisible(True)
|
2010-03-05 09:24:42 +00:00
|
|
|
if item.parent() is None:
|
2013-01-27 10:18:06 +00:00
|
|
|
self.notes_action.setVisible(True)
|
2013-08-31 18:17:38 +00:00
|
|
|
if service_item['service_item'].is_capable(ItemCapabilities.CanLoop) and \
|
|
|
|
len(service_item['service_item'].get_frames()) > 1:
|
2013-03-30 09:33:21 +00:00
|
|
|
self.auto_play_slides_menu.menuAction().setVisible(True)
|
2013-08-31 18:17:38 +00:00
|
|
|
self.auto_play_slides_once.setChecked(service_item['service_item'].auto_play_slides_once)
|
|
|
|
self.auto_play_slides_loop.setChecked(service_item['service_item'].auto_play_slides_loop)
|
|
|
|
self.timed_slide_interval.setChecked(service_item['service_item'].timed_slide_interval > 0)
|
|
|
|
if service_item['service_item'].timed_slide_interval > 0:
|
2016-05-20 16:22:06 +00:00
|
|
|
delay_suffix = ' {text} s'.format(text=str(service_item['service_item'].timed_slide_interval))
|
2012-11-09 18:44:25 +00:00
|
|
|
else:
|
2013-08-31 18:17:38 +00:00
|
|
|
delay_suffix = ' ...'
|
2013-02-01 21:34:23 +00:00
|
|
|
self.timed_slide_interval.setText(
|
|
|
|
translate('OpenLP.ServiceManager', '&Delay between slides') + delay_suffix)
|
2012-12-25 20:22:41 +00:00
|
|
|
# TODO for future: make group explains itself more visually
|
2012-11-09 18:44:25 +00:00
|
|
|
else:
|
2013-03-30 09:33:21 +00:00
|
|
|
self.auto_play_slides_menu.menuAction().setVisible(False)
|
2014-12-25 22:02:58 +00:00
|
|
|
if service_item['service_item'].is_capable(ItemCapabilities.HasVariableStartTime) and \
|
|
|
|
not service_item['service_item'].is_capable(ItemCapabilities.IsOptical):
|
2013-01-27 10:18:06 +00:00
|
|
|
self.time_action.setVisible(True)
|
2013-08-31 18:17:38 +00:00
|
|
|
if service_item['service_item'].is_capable(ItemCapabilities.CanAutoStartForLive):
|
2013-01-27 10:18:06 +00:00
|
|
|
self.auto_start_action.setVisible(True)
|
|
|
|
self.auto_start_action.setIcon(self.inactive)
|
2013-02-01 21:34:23 +00:00
|
|
|
self.auto_start_action.setText(translate('OpenLP.ServiceManager', '&Auto Start - inactive'))
|
2013-08-31 18:17:38 +00:00
|
|
|
if service_item['service_item'].will_auto_start:
|
2013-01-27 10:18:06 +00:00
|
|
|
self.auto_start_action.setText(translate('OpenLP.ServiceManager', '&Auto Start - active'))
|
|
|
|
self.auto_start_action.setIcon(self.active)
|
2013-08-31 18:17:38 +00:00
|
|
|
if service_item['service_item'].is_text():
|
2013-01-22 21:25:16 +00:00
|
|
|
for plugin in self.plugin_manager.plugins:
|
2013-08-31 18:17:38 +00:00
|
|
|
if plugin.name == 'custom' and plugin.status == PluginStatus.Active:
|
2012-12-23 00:00:24 +00:00
|
|
|
self.create_custom_action.setVisible(True)
|
|
|
|
break
|
2013-01-27 07:36:04 +00:00
|
|
|
self.theme_menu.menuAction().setVisible(False)
|
2011-05-27 06:29:14 +00:00
|
|
|
# Set up the theme menu.
|
2013-08-31 18:17:38 +00:00
|
|
|
if service_item['service_item'].is_text() and self.renderer.theme_level == ThemeLevel.Song:
|
2013-01-27 07:36:04 +00:00
|
|
|
self.theme_menu.menuAction().setVisible(True)
|
2011-05-27 06:29:14 +00:00
|
|
|
# The service item does not have a theme, check the "Default".
|
2013-08-31 18:17:38 +00:00
|
|
|
if service_item['service_item'].theme is None:
|
2013-01-27 10:18:06 +00:00
|
|
|
theme_action = self.theme_menu.defaultAction()
|
2011-05-26 08:15:56 +00:00
|
|
|
else:
|
2015-11-07 00:49:40 +00:00
|
|
|
theme_action = self.theme_menu.findChild(QtWidgets.QAction, service_item['service_item'].theme)
|
2013-01-27 10:18:06 +00:00
|
|
|
if theme_action is not None:
|
|
|
|
theme_action.setChecked(True)
|
2015-11-07 00:49:40 +00:00
|
|
|
self.menu.exec(self.service_manager_list.mapToGlobal(point))
|
2009-05-18 19:04:25 +00:00
|
|
|
|
2013-12-31 07:27:07 +00:00
|
|
|
def on_service_item_note_form(self, field=None):
|
2013-01-25 20:50:18 +00:00
|
|
|
"""
|
|
|
|
Allow the service note to be edited
|
2014-01-01 09:33:07 +00:00
|
|
|
:param field:
|
2013-01-25 20:50:18 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
item = self.find_service_item()[0]
|
2013-08-31 18:17:38 +00:00
|
|
|
self.service_note_form.text_edit.setPlainText(self.service_items[item]['service_item'].notes)
|
2015-11-07 00:49:40 +00:00
|
|
|
if self.service_note_form.exec():
|
2013-08-31 18:17:38 +00:00
|
|
|
self.service_items[item]['service_item'].notes = self.service_note_form.text_edit.toPlainText()
|
2013-01-27 20:36:18 +00:00
|
|
|
self.repaint_service_list(item, -1)
|
2013-01-27 07:36:04 +00:00
|
|
|
self.set_modified()
|
2010-03-03 17:48:37 +00:00
|
|
|
|
2013-12-31 07:27:07 +00:00
|
|
|
def on_start_time_form(self, field=None):
|
2011-08-14 13:05:39 +00:00
|
|
|
"""
|
|
|
|
Opens a dialog to type in service item notes.
|
2014-01-01 09:33:07 +00:00
|
|
|
:param field:
|
2011-08-14 13:05:39 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
item = self.find_service_item()[0]
|
2013-03-06 22:23:01 +00:00
|
|
|
self.start_time_form.item = self.service_items[item]
|
2015-11-07 00:49:40 +00:00
|
|
|
if self.start_time_form.exec():
|
2013-01-27 20:36:18 +00:00
|
|
|
self.repaint_service_list(item, -1)
|
2011-02-12 10:04:10 +00:00
|
|
|
|
2013-12-31 20:29:03 +00:00
|
|
|
def toggle_auto_play_slides_once(self, field=None):
|
2012-11-09 18:44:25 +00:00
|
|
|
"""
|
2013-03-29 12:53:07 +00:00
|
|
|
Toggle Auto play slide once. Inverts auto play once option for the item
|
2014-01-04 16:33:20 +00:00
|
|
|
|
2014-01-01 09:33:07 +00:00
|
|
|
:param field:
|
2012-11-09 18:44:25 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
item = self.find_service_item()[0]
|
2013-08-31 18:17:38 +00:00
|
|
|
service_item = self.service_items[item]['service_item']
|
2012-11-14 11:47:15 +00:00
|
|
|
service_item.auto_play_slides_once = not service_item.auto_play_slides_once
|
|
|
|
if service_item.auto_play_slides_once:
|
|
|
|
service_item.auto_play_slides_loop = False
|
2013-01-27 07:36:04 +00:00
|
|
|
self.auto_play_slides_loop.setChecked(False)
|
2012-11-14 11:47:15 +00:00
|
|
|
if service_item.auto_play_slides_once and service_item.timed_slide_interval == 0:
|
2013-01-24 09:18:38 +00:00
|
|
|
service_item.timed_slide_interval = Settings().value(
|
2013-08-31 18:17:38 +00:00
|
|
|
self.main_window.general_settings_section + '/loop delay')
|
2013-01-27 07:36:04 +00:00
|
|
|
self.set_modified()
|
2012-11-09 18:44:25 +00:00
|
|
|
|
2013-12-31 20:29:03 +00:00
|
|
|
def toggle_auto_play_slides_loop(self, field=None):
|
2012-11-09 18:44:25 +00:00
|
|
|
"""
|
|
|
|
Toggle Auto play slide loop.
|
2014-01-04 16:33:20 +00:00
|
|
|
|
2014-01-01 09:33:07 +00:00
|
|
|
:param field:
|
2012-11-09 18:44:25 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
item = self.find_service_item()[0]
|
2013-08-31 18:17:38 +00:00
|
|
|
service_item = self.service_items[item]['service_item']
|
2012-11-14 11:47:15 +00:00
|
|
|
service_item.auto_play_slides_loop = not service_item.auto_play_slides_loop
|
|
|
|
if service_item.auto_play_slides_loop:
|
|
|
|
service_item.auto_play_slides_once = False
|
2013-01-27 07:36:04 +00:00
|
|
|
self.auto_play_slides_once.setChecked(False)
|
2012-11-14 11:47:15 +00:00
|
|
|
if service_item.auto_play_slides_loop and service_item.timed_slide_interval == 0:
|
2013-01-24 09:18:38 +00:00
|
|
|
service_item.timed_slide_interval = Settings().value(
|
2013-08-31 18:17:38 +00:00
|
|
|
self.main_window.general_settings_section + '/loop delay')
|
2013-01-27 07:36:04 +00:00
|
|
|
self.set_modified()
|
2012-11-09 18:44:25 +00:00
|
|
|
|
2013-12-31 07:27:07 +00:00
|
|
|
def on_timed_slide_interval(self, field=None):
|
2012-11-09 18:44:25 +00:00
|
|
|
"""
|
2012-12-29 22:52:19 +00:00
|
|
|
Shows input dialog for enter interval in seconds for delay
|
2014-01-01 09:33:07 +00:00
|
|
|
:param field:
|
2012-11-09 18:44:25 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
item = self.find_service_item()[0]
|
2013-08-31 18:17:38 +00:00
|
|
|
service_item = self.service_items[item]['service_item']
|
2012-11-14 11:47:15 +00:00
|
|
|
if service_item.timed_slide_interval == 0:
|
2013-08-31 18:17:38 +00:00
|
|
|
timed_slide_interval = Settings().value(self.main_window.general_settings_section + '/loop delay')
|
2012-11-09 18:44:25 +00:00
|
|
|
else:
|
2012-11-14 11:47:15 +00:00
|
|
|
timed_slide_interval = service_item.timed_slide_interval
|
2015-11-07 00:49:40 +00:00
|
|
|
timed_slide_interval, ok = QtWidgets.QInputDialog.getInt(self, translate('OpenLP.ServiceManager',
|
2013-12-24 21:24:52 +00:00
|
|
|
'Input delay'),
|
|
|
|
translate('OpenLP.ServiceManager',
|
|
|
|
'Delay between slides in seconds.'),
|
2013-12-24 15:55:01 +00:00
|
|
|
timed_slide_interval, 0, 180, 1)
|
2012-11-09 18:44:25 +00:00
|
|
|
if ok:
|
2012-11-14 11:47:15 +00:00
|
|
|
service_item.timed_slide_interval = timed_slide_interval
|
2013-01-21 11:11:47 +00:00
|
|
|
if service_item.timed_slide_interval != 0 and not service_item.auto_play_slides_loop \
|
|
|
|
and not service_item.auto_play_slides_once:
|
2012-11-14 11:47:15 +00:00
|
|
|
service_item.auto_play_slides_loop = True
|
|
|
|
elif service_item.timed_slide_interval == 0:
|
|
|
|
service_item.auto_play_slides_loop = False
|
|
|
|
service_item.auto_play_slides_once = False
|
2013-01-27 07:36:04 +00:00
|
|
|
self.set_modified()
|
2012-11-09 18:44:25 +00:00
|
|
|
|
2014-08-23 20:42:10 +00:00
|
|
|
def on_auto_start(self, field=None):
|
2012-09-09 06:27:53 +00:00
|
|
|
"""
|
|
|
|
Toggles to Auto Start Setting.
|
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
item = self.find_service_item()[0]
|
2013-08-31 18:17:38 +00:00
|
|
|
self.service_items[item]['service_item'].will_auto_start = \
|
|
|
|
not self.service_items[item]['service_item'].will_auto_start
|
2012-09-09 06:27:53 +00:00
|
|
|
|
2013-12-31 07:27:07 +00:00
|
|
|
def on_service_item_edit_form(self, field=None):
|
2012-08-24 20:06:56 +00:00
|
|
|
"""
|
2013-03-29 12:53:07 +00:00
|
|
|
Opens a dialog to edit the service item and update the service display if changes are saved.
|
2014-01-01 09:33:07 +00:00
|
|
|
:param field:
|
2012-08-24 20:06:56 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
item = self.find_service_item()[0]
|
2013-08-31 18:17:38 +00:00
|
|
|
self.service_item_edit_form.set_service_item(self.service_items[item]['service_item'])
|
2015-11-07 00:49:40 +00:00
|
|
|
if self.service_item_edit_form.exec():
|
2013-03-06 22:23:01 +00:00
|
|
|
self.add_service_item(self.service_item_edit_form.get_service_item(),
|
2013-12-24 15:55:01 +00:00
|
|
|
replace=True, expand=self.service_items[item]['expanded'])
|
2010-03-17 21:25:35 +00:00
|
|
|
|
2013-02-03 09:07:31 +00:00
|
|
|
def preview_live(self, unique_identifier, row):
|
2011-03-23 21:08:24 +00:00
|
|
|
"""
|
2013-03-29 12:53:07 +00:00
|
|
|
Called by the SlideController to request a preview item be made live and allows the next preview to be updated
|
|
|
|
if relevant.
|
2013-02-03 09:07:31 +00:00
|
|
|
|
2014-01-01 09:33:07 +00:00
|
|
|
:param unique_identifier: Reference to the service_item
|
|
|
|
:param row: individual row number
|
2011-03-23 21:08:24 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
for sitem in self.service_items:
|
2013-08-31 18:17:38 +00:00
|
|
|
if sitem['service_item'].unique_identifier == unique_identifier:
|
|
|
|
item = self.service_manager_list.topLevelItem(sitem['order'] - 1)
|
2013-01-27 07:36:04 +00:00
|
|
|
self.service_manager_list.setCurrentItem(item)
|
|
|
|
self.make_live(int(row))
|
2011-03-23 21:08:24 +00:00
|
|
|
return
|
|
|
|
|
2013-01-27 07:36:04 +00:00
|
|
|
def next_item(self):
|
2010-02-03 18:29:02 +00:00
|
|
|
"""
|
2011-01-23 06:56:58 +00:00
|
|
|
Called by the SlideController to select the next service item.
|
2010-02-03 18:29:02 +00:00
|
|
|
"""
|
2014-01-09 19:52:20 +00:00
|
|
|
if not self.service_manager_list.selectedItems():
|
2010-02-04 19:25:32 +00:00
|
|
|
return
|
2014-01-09 19:52:20 +00:00
|
|
|
selected = self.service_manager_list.selectedItems()[0]
|
2013-12-26 08:56:53 +00:00
|
|
|
look_for = 0
|
2015-11-07 00:49:40 +00:00
|
|
|
service_iterator = QtWidgets.QTreeWidgetItemIterator(self.service_manager_list)
|
2013-12-26 08:56:53 +00:00
|
|
|
while service_iterator.value():
|
|
|
|
if look_for == 1 and service_iterator.value().parent() is None:
|
|
|
|
self.service_manager_list.setCurrentItem(service_iterator.value())
|
2013-01-27 07:36:04 +00:00
|
|
|
self.make_live()
|
2010-02-03 18:29:02 +00:00
|
|
|
return
|
2013-12-26 08:56:53 +00:00
|
|
|
if service_iterator.value() == selected:
|
|
|
|
look_for = 1
|
|
|
|
service_iterator += 1
|
2010-02-03 18:29:02 +00:00
|
|
|
|
2013-02-03 09:07:31 +00:00
|
|
|
def previous_item(self, last_slide=False):
|
2010-04-26 21:29:40 +00:00
|
|
|
"""
|
2011-01-23 06:56:58 +00:00
|
|
|
Called by the SlideController to select the previous service item.
|
2013-02-03 09:07:31 +00:00
|
|
|
|
2014-01-01 09:33:07 +00:00
|
|
|
:param last_slide: Is this the last slide in the service_item.
|
2010-04-26 21:29:40 +00:00
|
|
|
"""
|
2014-01-09 19:52:20 +00:00
|
|
|
if not self.service_manager_list.selectedItems():
|
2010-04-26 21:29:40 +00:00
|
|
|
return
|
2014-01-09 19:52:20 +00:00
|
|
|
selected = self.service_manager_list.selectedItems()[0]
|
2013-12-26 08:56:53 +00:00
|
|
|
prev_item = None
|
|
|
|
prev_item_last_slide = None
|
2015-11-07 00:49:40 +00:00
|
|
|
service_iterator = QtWidgets.QTreeWidgetItemIterator(self.service_manager_list)
|
2013-12-26 08:56:53 +00:00
|
|
|
while service_iterator.value():
|
|
|
|
if service_iterator.value() == selected:
|
|
|
|
if last_slide and prev_item_last_slide:
|
|
|
|
pos = prev_item.data(0, QtCore.Qt.UserRole)
|
2013-08-31 18:17:38 +00:00
|
|
|
check_expanded = self.service_items[pos - 1]['expanded']
|
2013-12-26 08:56:53 +00:00
|
|
|
self.service_manager_list.setCurrentItem(prev_item_last_slide)
|
2012-01-22 09:07:59 +00:00
|
|
|
if not check_expanded:
|
2013-12-26 08:56:53 +00:00
|
|
|
self.service_manager_list.collapseItem(prev_item)
|
2013-01-27 07:36:04 +00:00
|
|
|
self.make_live()
|
2013-12-26 08:56:53 +00:00
|
|
|
self.service_manager_list.setCurrentItem(prev_item)
|
|
|
|
elif prev_item:
|
|
|
|
self.service_manager_list.setCurrentItem(prev_item)
|
2013-01-27 07:36:04 +00:00
|
|
|
self.make_live()
|
2010-04-26 21:29:40 +00:00
|
|
|
return
|
2013-12-26 08:56:53 +00:00
|
|
|
if service_iterator.value().parent() is None:
|
|
|
|
prev_item = service_iterator.value()
|
|
|
|
if service_iterator.value().parent() is prev_item:
|
|
|
|
prev_item_last_slide = service_iterator.value()
|
|
|
|
service_iterator += 1
|
2010-04-26 21:29:40 +00:00
|
|
|
|
2013-12-31 07:27:07 +00:00
|
|
|
def on_set_item(self, message, field=None):
|
2010-04-28 22:08:37 +00:00
|
|
|
"""
|
2013-03-20 20:17:00 +00:00
|
|
|
Called by a signal to select a specific item and make it live usually from remote.
|
2014-01-01 09:33:07 +00:00
|
|
|
|
|
|
|
:param field:
|
|
|
|
:param message: The data passed in from a remove message
|
2010-04-28 22:08:37 +00:00
|
|
|
"""
|
2014-06-01 17:12:00 +00:00
|
|
|
self.log_debug(message)
|
2013-01-27 07:36:04 +00:00
|
|
|
self.set_item(int(message))
|
2010-05-04 20:01:45 +00:00
|
|
|
|
2013-01-27 07:36:04 +00:00
|
|
|
def set_item(self, index):
|
2010-04-28 22:08:37 +00:00
|
|
|
"""
|
2011-01-23 06:56:58 +00:00
|
|
|
Makes a specific item in the service live.
|
2014-01-01 09:33:07 +00:00
|
|
|
|
|
|
|
:param index: The index of the service item list to be actioned.
|
2010-04-28 22:08:37 +00:00
|
|
|
"""
|
2014-06-01 17:12:00 +00:00
|
|
|
if 0 <= index < self.service_manager_list.topLevelItemCount():
|
2013-01-27 07:36:04 +00:00
|
|
|
item = self.service_manager_list.topLevelItem(index)
|
|
|
|
self.service_manager_list.setCurrentItem(item)
|
|
|
|
self.make_live()
|
2010-04-28 22:08:37 +00:00
|
|
|
|
2013-01-27 07:36:04 +00:00
|
|
|
def on_move_selection_up(self):
|
2009-07-21 20:04:27 +00:00
|
|
|
"""
|
2013-03-29 12:53:07 +00:00
|
|
|
Moves the cursor selection up the window. Called by the up arrow.
|
2009-07-21 20:04:27 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
item = self.service_manager_list.currentItem()
|
2014-07-07 11:17:24 +00:00
|
|
|
item_before = self.service_manager_list.itemAbove(item)
|
2013-12-26 08:56:53 +00:00
|
|
|
if item_before is None:
|
2011-07-23 05:48:55 +00:00
|
|
|
return
|
2013-12-26 08:56:53 +00:00
|
|
|
self.service_manager_list.setCurrentItem(item_before)
|
2009-07-21 20:04:27 +00:00
|
|
|
|
2013-01-27 07:36:04 +00:00
|
|
|
def on_move_selection_down(self):
|
2009-07-21 20:04:27 +00:00
|
|
|
"""
|
2013-03-29 12:53:07 +00:00
|
|
|
Moves the cursor selection down the window. Called by the down arrow.
|
2009-07-21 20:04:27 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
item = self.service_manager_list.currentItem()
|
2013-12-26 08:56:53 +00:00
|
|
|
item_after = self.service_manager_list.itemBelow(item)
|
|
|
|
if item_after is None:
|
2011-07-23 05:48:55 +00:00
|
|
|
return
|
2013-12-26 08:56:53 +00:00
|
|
|
self.service_manager_list.setCurrentItem(item_after)
|
2009-07-21 20:04:27 +00:00
|
|
|
|
2017-06-13 15:49:48 +00:00
|
|
|
def on_expand_selection(self):
|
|
|
|
"""
|
|
|
|
Expands cursor selection on the window. Called by the right arrow
|
|
|
|
"""
|
|
|
|
item = self.service_manager_list.currentItem()
|
2017-06-15 18:05:38 +00:00
|
|
|
# Since we only have 2 levels we find them by checking for children
|
|
|
|
if item.childCount():
|
2017-06-13 15:49:48 +00:00
|
|
|
if not self.service_manager_list.isExpanded(self.service_manager_list.currentIndex()):
|
|
|
|
self.service_manager_list.expandItem(item)
|
|
|
|
self.service_manager.expanded(item)
|
|
|
|
# If not expanded, Expand it
|
|
|
|
self.service_manager_list.setCurrentItem(self.service_manager_list.itemBelow(item))
|
|
|
|
# Then move selection down to child whether it needed to be expanded or not
|
|
|
|
|
|
|
|
def on_collapse_selection(self):
|
|
|
|
"""
|
|
|
|
Collapses cursor selection on the window Called by the left arrow
|
|
|
|
"""
|
|
|
|
item = self.service_manager_list.currentItem()
|
2017-06-15 18:05:38 +00:00
|
|
|
# Since we only have 2 levels we find them by checking for children
|
|
|
|
if item.childCount():
|
2017-06-13 15:49:48 +00:00
|
|
|
if self.service_manager_list.isExpanded(self.service_manager_list.currentIndex()):
|
|
|
|
self.service_manager_list.collapseItem(item)
|
|
|
|
self.service_manager.collapsed(item)
|
|
|
|
else: # If selection is lower level
|
|
|
|
self.service_manager_list.collapseItem(item.parent())
|
|
|
|
self.service_manager.collapsed(item.parent())
|
|
|
|
self.service_manager_list.setCurrentItem(item.parent())
|
|
|
|
|
2013-12-31 20:29:03 +00:00
|
|
|
def on_collapse_all(self, field=None):
|
2010-10-08 19:15:01 +00:00
|
|
|
"""
|
2011-01-23 06:56:58 +00:00
|
|
|
Collapse all the service items.
|
2014-01-01 09:33:07 +00:00
|
|
|
:param field:
|
2010-10-08 19:15:01 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
for item in self.service_items:
|
2013-08-31 18:17:38 +00:00
|
|
|
item['expanded'] = False
|
2013-01-27 07:36:04 +00:00
|
|
|
self.service_manager_list.collapseAll()
|
2010-10-08 19:15:01 +00:00
|
|
|
|
2009-06-20 07:08:17 +00:00
|
|
|
def collapsed(self, item):
|
2009-07-11 05:18:34 +00:00
|
|
|
"""
|
2013-03-29 12:53:07 +00:00
|
|
|
Record if an item is collapsed. Used when repainting the list to get the correct state.
|
2014-01-01 09:33:07 +00:00
|
|
|
|
|
|
|
:param item: The service item to be checked
|
2009-07-11 05:18:34 +00:00
|
|
|
"""
|
2012-05-19 09:13:32 +00:00
|
|
|
pos = item.data(0, QtCore.Qt.UserRole)
|
2016-01-12 21:29:20 +00:00
|
|
|
# Only set root items as collapsed, and since we only have 2 levels we find them by checking for children
|
|
|
|
if item.childCount():
|
|
|
|
self.service_items[pos - 1]['expanded'] = False
|
2009-06-20 07:08:17 +00:00
|
|
|
|
2013-12-31 20:29:03 +00:00
|
|
|
def on_expand_all(self, field=None):
|
2010-10-08 19:15:01 +00:00
|
|
|
"""
|
2011-01-23 06:56:58 +00:00
|
|
|
Collapse all the service items.
|
2014-01-01 09:33:07 +00:00
|
|
|
:param field:
|
2010-10-08 19:15:01 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
for item in self.service_items:
|
2013-08-31 18:17:38 +00:00
|
|
|
item['expanded'] = True
|
2013-01-27 07:36:04 +00:00
|
|
|
self.service_manager_list.expandAll()
|
2010-10-08 19:15:01 +00:00
|
|
|
|
2009-06-20 07:08:17 +00:00
|
|
|
def expanded(self, item):
|
2009-07-11 05:18:34 +00:00
|
|
|
"""
|
2013-03-29 12:53:07 +00:00
|
|
|
Record if an item is collapsed. Used when repainting the list to get the correct state.
|
2014-01-01 09:33:07 +00:00
|
|
|
|
|
|
|
:param item: The service item to be checked
|
2009-07-11 05:18:34 +00:00
|
|
|
"""
|
2012-05-19 09:13:32 +00:00
|
|
|
pos = item.data(0, QtCore.Qt.UserRole)
|
2016-01-12 21:29:20 +00:00
|
|
|
# Only set root items as expanded, and since we only have 2 levels we find them by checking for children
|
|
|
|
if item.childCount():
|
|
|
|
self.service_items[pos - 1]['expanded'] = True
|
2009-06-20 07:08:17 +00:00
|
|
|
|
2013-12-31 20:29:03 +00:00
|
|
|
def on_service_top(self, field=None):
|
2009-06-08 19:03:16 +00:00
|
|
|
"""
|
2011-01-23 06:56:58 +00:00
|
|
|
Move the current ServiceItem to the top of the list.
|
2014-01-01 09:33:07 +00:00
|
|
|
:param field:
|
2009-06-08 19:03:16 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
item, child = self.find_service_item()
|
|
|
|
if item < len(self.service_items) and item != -1:
|
|
|
|
temp = self.service_items[item]
|
|
|
|
self.service_items.remove(self.service_items[item])
|
|
|
|
self.service_items.insert(0, temp)
|
2013-01-27 20:36:18 +00:00
|
|
|
self.repaint_service_list(0, child)
|
2013-01-27 07:36:04 +00:00
|
|
|
self.set_modified()
|
2009-05-04 08:15:48 +00:00
|
|
|
|
2013-12-31 20:29:03 +00:00
|
|
|
def on_service_up(self, field=None):
|
2009-06-08 19:03:16 +00:00
|
|
|
"""
|
2011-01-23 06:56:58 +00:00
|
|
|
Move the current ServiceItem one position up in the list.
|
2014-01-01 09:33:07 +00:00
|
|
|
:param field:
|
2009-06-08 19:03:16 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
item, child = self.find_service_item()
|
2009-06-19 18:41:38 +00:00
|
|
|
if item > 0:
|
2013-01-27 07:36:04 +00:00
|
|
|
temp = self.service_items[item]
|
|
|
|
self.service_items.remove(self.service_items[item])
|
|
|
|
self.service_items.insert(item - 1, temp)
|
2013-01-27 20:36:18 +00:00
|
|
|
self.repaint_service_list(item - 1, child)
|
2013-01-27 07:36:04 +00:00
|
|
|
self.set_modified()
|
2009-05-04 08:15:48 +00:00
|
|
|
|
2013-12-31 20:29:03 +00:00
|
|
|
def on_service_down(self, field=None):
|
2009-06-08 19:03:16 +00:00
|
|
|
"""
|
2011-01-23 06:56:58 +00:00
|
|
|
Move the current ServiceItem one position down in the list.
|
2014-01-01 09:33:07 +00:00
|
|
|
:param field:
|
2009-06-08 19:03:16 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
item, child = self.find_service_item()
|
|
|
|
if item < len(self.service_items) and item != -1:
|
|
|
|
temp = self.service_items[item]
|
|
|
|
self.service_items.remove(self.service_items[item])
|
|
|
|
self.service_items.insert(item + 1, temp)
|
2013-01-27 20:36:18 +00:00
|
|
|
self.repaint_service_list(item + 1, child)
|
2013-01-27 07:36:04 +00:00
|
|
|
self.set_modified()
|
2009-05-04 08:15:48 +00:00
|
|
|
|
2013-12-31 20:29:03 +00:00
|
|
|
def on_service_end(self, field=None):
|
2009-06-08 19:03:16 +00:00
|
|
|
"""
|
2011-01-23 06:56:58 +00:00
|
|
|
Move the current ServiceItem to the bottom of the list.
|
2014-01-01 09:33:07 +00:00
|
|
|
:param field:
|
2009-06-08 19:03:16 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
item, child = self.find_service_item()
|
|
|
|
if item < len(self.service_items) and item != -1:
|
|
|
|
temp = self.service_items[item]
|
|
|
|
self.service_items.remove(self.service_items[item])
|
|
|
|
self.service_items.insert(len(self.service_items), temp)
|
2013-01-27 20:36:18 +00:00
|
|
|
self.repaint_service_list(len(self.service_items) - 1, child)
|
2013-01-27 07:36:04 +00:00
|
|
|
self.set_modified()
|
2009-05-04 08:15:48 +00:00
|
|
|
|
2013-12-31 07:27:07 +00:00
|
|
|
def on_delete_from_service(self, field=None):
|
2009-06-08 19:03:16 +00:00
|
|
|
"""
|
2011-01-23 06:56:58 +00:00
|
|
|
Remove the current ServiceItem from the list.
|
2014-01-01 09:33:07 +00:00
|
|
|
:param field:
|
2009-06-08 19:03:16 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
item = self.find_service_item()[0]
|
2011-01-23 06:56:58 +00:00
|
|
|
if item != -1:
|
2013-01-27 07:36:04 +00:00
|
|
|
self.service_items.remove(self.service_items[item])
|
2013-01-27 20:36:18 +00:00
|
|
|
self.repaint_service_list(item - 1, -1)
|
2013-01-27 07:36:04 +00:00
|
|
|
self.set_modified()
|
2009-06-19 18:41:38 +00:00
|
|
|
|
2013-03-06 22:23:01 +00:00
|
|
|
def repaint_service_list(self, service_item, service_item_child):
|
2009-07-11 05:18:34 +00:00
|
|
|
"""
|
2013-03-29 12:53:07 +00:00
|
|
|
Clear the existing service list and prepaint all the items. This is used when moving items as the move takes
|
|
|
|
place in a supporting list, and when regenerating all the items due to theme changes.
|
2010-12-31 21:43:02 +00:00
|
|
|
|
2014-01-01 09:33:07 +00:00
|
|
|
:param service_item: The item which changed. (int)
|
|
|
|
:param service_item_child: The child of the ``service_item``, which will be selected. (int)
|
2009-07-11 05:18:34 +00:00
|
|
|
"""
|
2010-10-08 19:15:01 +00:00
|
|
|
# Correct order of items in array
|
2009-06-19 18:41:38 +00:00
|
|
|
count = 1
|
2012-12-08 16:20:52 +00:00
|
|
|
self.service_has_all_original_files = True
|
2013-01-27 07:36:04 +00:00
|
|
|
for item in self.service_items:
|
2013-08-31 18:17:38 +00:00
|
|
|
item['order'] = count
|
2009-06-19 18:41:38 +00:00
|
|
|
count += 1
|
2013-08-31 18:17:38 +00:00
|
|
|
if not item['service_item'].has_original_files:
|
2012-12-08 16:20:52 +00:00
|
|
|
self.service_has_all_original_files = False
|
2010-10-08 19:15:01 +00:00
|
|
|
# Repaint the screen
|
2013-01-27 07:36:04 +00:00
|
|
|
self.service_manager_list.clear()
|
2013-03-11 19:11:46 +00:00
|
|
|
self.service_manager_list.clearSelection()
|
2013-01-27 07:36:04 +00:00
|
|
|
for item_count, item in enumerate(self.service_items):
|
2013-12-26 08:56:53 +00:00
|
|
|
service_item_from_item = item['service_item']
|
2015-11-07 00:49:40 +00:00
|
|
|
tree_widget_item = QtWidgets.QTreeWidgetItem(self.service_manager_list)
|
2013-12-26 08:56:53 +00:00
|
|
|
if service_item_from_item.is_valid:
|
|
|
|
if service_item_from_item.notes:
|
|
|
|
icon = QtGui.QImage(service_item_from_item.icon)
|
2012-12-10 18:04:58 +00:00
|
|
|
icon = icon.scaled(80, 80, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
|
2010-05-04 20:01:45 +00:00
|
|
|
overlay = QtGui.QImage(':/services/service_item_notes.png')
|
2012-12-10 18:04:58 +00:00
|
|
|
overlay = overlay.scaled(80, 80, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
|
2010-05-04 20:01:45 +00:00
|
|
|
painter = QtGui.QPainter(icon)
|
|
|
|
painter.drawImage(0, 0, overlay)
|
|
|
|
painter.end()
|
2013-12-26 08:56:53 +00:00
|
|
|
tree_widget_item.setIcon(0, build_icon(icon))
|
|
|
|
elif service_item_from_item.temporary_edit:
|
|
|
|
icon = QtGui.QImage(service_item_from_item.icon)
|
2012-12-10 18:04:58 +00:00
|
|
|
icon = icon.scaled(80, 80, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
|
2011-12-10 08:45:17 +00:00
|
|
|
overlay = QtGui.QImage(':/general/general_export.png')
|
2012-12-10 18:04:58 +00:00
|
|
|
overlay = overlay.scaled(40, 40, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
|
2011-12-10 08:45:17 +00:00
|
|
|
painter = QtGui.QPainter(icon)
|
|
|
|
painter.drawImage(40, 0, overlay)
|
|
|
|
painter.end()
|
2013-12-26 08:56:53 +00:00
|
|
|
tree_widget_item.setIcon(0, build_icon(icon))
|
2010-05-04 20:01:45 +00:00
|
|
|
else:
|
2013-12-26 08:56:53 +00:00
|
|
|
tree_widget_item.setIcon(0, service_item_from_item.iconic_representation)
|
2010-03-06 08:00:36 +00:00
|
|
|
else:
|
2013-12-26 08:56:53 +00:00
|
|
|
tree_widget_item.setIcon(0, build_icon(':/general/general_delete.png'))
|
|
|
|
tree_widget_item.setText(0, service_item_from_item.get_display_title())
|
2011-07-08 20:55:18 +00:00
|
|
|
tips = []
|
2013-12-26 08:56:53 +00:00
|
|
|
if service_item_from_item.temporary_edit:
|
2016-05-20 16:22:06 +00:00
|
|
|
text1 = translate('OpenLP.ServiceManager', 'Edit')
|
|
|
|
text2 = translate('OpenLP.ServiceManager', 'Service copy only')
|
|
|
|
tips.append('<strong>{text1}:</strong> <em>{text2}</em>'.format(text1=text1, text2=text2))
|
2013-12-26 08:56:53 +00:00
|
|
|
if service_item_from_item.theme and service_item_from_item.theme != -1:
|
2016-05-20 16:22:06 +00:00
|
|
|
text = translate('OpenLP.ServiceManager', 'Slide theme')
|
|
|
|
tips.append('<strong>{text1}:</strong> <em>{text2}</em>'.format(text1=text,
|
|
|
|
text2=service_item_from_item.theme))
|
2013-12-26 08:56:53 +00:00
|
|
|
if service_item_from_item.notes:
|
2016-05-20 16:22:06 +00:00
|
|
|
text1 = translate('OpenLP.ServiceManager', 'Notes')
|
|
|
|
text2 = html.escape(service_item_from_item.notes)
|
|
|
|
tips.append('<strong>{text1}: </strong> {text2}'.format(text1=text1, text2=text2))
|
2013-08-31 18:17:38 +00:00
|
|
|
if item['service_item'].is_capable(ItemCapabilities.HasVariableStartTime):
|
|
|
|
tips.append(item['service_item'].get_media_time())
|
2013-12-26 08:56:53 +00:00
|
|
|
tree_widget_item.setToolTip(0, '<br>'.join(tips))
|
|
|
|
tree_widget_item.setData(0, QtCore.Qt.UserRole, item['order'])
|
|
|
|
tree_widget_item.setSelected(item['selected'])
|
2014-07-11 21:45:01 +00:00
|
|
|
# Add the children to their parent tree_widget_item.
|
2013-12-26 08:56:53 +00:00
|
|
|
for count, frame in enumerate(service_item_from_item.get_frames()):
|
2015-11-07 00:49:40 +00:00
|
|
|
child = QtWidgets.QTreeWidgetItem(tree_widget_item)
|
2013-10-28 02:33:28 +00:00
|
|
|
# prefer to use a display_title
|
2013-12-30 08:53:51 +00:00
|
|
|
if service_item_from_item.is_capable(ItemCapabilities.HasDisplayTitle):
|
|
|
|
text = frame['display_title'].replace('\n', ' ')
|
2013-10-19 05:27:25 +00:00
|
|
|
else:
|
|
|
|
text = frame['title'].replace('\n', ' ')
|
2011-01-22 07:31:32 +00:00
|
|
|
child.setText(0, text[:40])
|
2012-05-17 15:13:09 +00:00
|
|
|
child.setData(0, QtCore.Qt.UserRole, count)
|
2013-03-06 22:23:01 +00:00
|
|
|
if service_item == item_count:
|
2013-08-31 18:17:38 +00:00
|
|
|
if item['expanded'] and service_item_child == count:
|
2013-01-27 07:36:04 +00:00
|
|
|
self.service_manager_list.setCurrentItem(child)
|
2013-03-06 22:23:01 +00:00
|
|
|
elif service_item_child == -1:
|
2013-12-26 08:56:53 +00:00
|
|
|
self.service_manager_list.setCurrentItem(tree_widget_item)
|
|
|
|
tree_widget_item.setExpanded(item['expanded'])
|
2009-05-04 08:15:48 +00:00
|
|
|
|
2013-02-01 20:40:23 +00:00
|
|
|
def clean_up(self):
|
2009-09-19 21:45:50 +00:00
|
|
|
"""
|
2013-12-26 08:56:53 +00:00
|
|
|
Empties the service_path of temporary files on system exit.
|
2009-09-19 21:45:50 +00:00
|
|
|
"""
|
2013-12-26 08:56:53 +00:00
|
|
|
for file_name in os.listdir(self.service_path):
|
2017-08-12 17:45:56 +00:00
|
|
|
file_path = Path(self.service_path, file_name)
|
2011-01-14 18:58:47 +00:00
|
|
|
delete_file(file_path)
|
2013-12-26 08:56:53 +00:00
|
|
|
if os.path.exists(os.path.join(self.service_path, 'audio')):
|
|
|
|
shutil.rmtree(os.path.join(self.service_path, 'audio'), True)
|
2009-05-04 08:15:48 +00:00
|
|
|
|
2013-12-30 19:50:34 +00:00
|
|
|
def on_theme_combo_box_selected(self, current_index):
|
2009-06-08 19:03:16 +00:00
|
|
|
"""
|
2011-01-23 06:56:58 +00:00
|
|
|
Set the theme for the current service.
|
2014-01-01 09:33:07 +00:00
|
|
|
|
|
|
|
:param current_index: The combo box index for the selected item
|
2009-06-08 19:03:16 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
self.service_theme = self.theme_combo_box.currentText()
|
2013-01-22 21:09:43 +00:00
|
|
|
self.renderer.set_service_theme(self.service_theme)
|
2013-08-31 18:17:38 +00:00
|
|
|
Settings().setValue(self.main_window.service_manager_settings_section + '/service theme', self.service_theme)
|
2013-12-26 08:56:53 +00:00
|
|
|
self.regenerate_service_items(True)
|
2009-06-26 16:39:16 +00:00
|
|
|
|
2013-03-14 20:21:04 +00:00
|
|
|
def theme_change(self):
|
2010-06-26 07:19:30 +00:00
|
|
|
"""
|
2013-03-29 12:53:07 +00:00
|
|
|
The theme may have changed in the settings dialog so make sure the theme combo box is in the correct state.
|
2010-06-26 07:19:30 +00:00
|
|
|
"""
|
2016-07-01 21:17:20 +00:00
|
|
|
visible = self.renderer.theme_level != ThemeLevel.Global
|
2016-05-17 21:28:27 +00:00
|
|
|
self.toolbar.actions['theme_combo_box'].setVisible(visible)
|
|
|
|
self.toolbar.actions['theme_label'].setVisible(visible)
|
2016-03-29 15:45:59 +00:00
|
|
|
self.regenerate_service_items()
|
2010-06-26 07:19:30 +00:00
|
|
|
|
2013-12-26 08:56:53 +00:00
|
|
|
def regenerate_service_items(self, changed=False):
|
2010-05-23 07:03:28 +00:00
|
|
|
"""
|
2013-03-29 12:53:07 +00:00
|
|
|
Rebuild the service list as things have changed and a repaint is the easiest way to do this.
|
2014-01-01 09:33:07 +00:00
|
|
|
|
|
|
|
:param changed: True if the list has changed for new / removed items. False for a theme change.
|
2010-05-23 07:03:28 +00:00
|
|
|
"""
|
2013-02-03 19:23:12 +00:00
|
|
|
self.application.set_busy_cursor()
|
2010-08-26 05:01:29 +00:00
|
|
|
# force reset of renderer as theme data has changed
|
2012-12-08 16:20:52 +00:00
|
|
|
self.service_has_all_original_files = True
|
2013-01-27 07:36:04 +00:00
|
|
|
if self.service_items:
|
|
|
|
for item in self.service_items:
|
2013-08-31 18:17:38 +00:00
|
|
|
item['selected'] = False
|
2015-11-07 00:49:40 +00:00
|
|
|
service_iterator = QtWidgets.QTreeWidgetItemIterator(self.service_manager_list)
|
2013-12-26 08:56:53 +00:00
|
|
|
selected_item = None
|
|
|
|
while service_iterator.value():
|
|
|
|
if service_iterator.value().isSelected():
|
|
|
|
selected_item = service_iterator.value()
|
|
|
|
service_iterator += 1
|
|
|
|
if selected_item is not None:
|
|
|
|
if selected_item.parent() is None:
|
|
|
|
pos = selected_item.data(0, QtCore.Qt.UserRole)
|
2011-06-04 18:08:48 +00:00
|
|
|
else:
|
2013-12-26 08:56:53 +00:00
|
|
|
pos = selected_item.parent().data(0, QtCore.Qt.UserRole)
|
2013-08-31 18:17:38 +00:00
|
|
|
self.service_items[pos - 1]['selected'] = True
|
2013-12-26 08:56:53 +00:00
|
|
|
temp_service_items = self.service_items
|
2013-01-27 07:36:04 +00:00
|
|
|
self.service_manager_list.clear()
|
|
|
|
self.service_items = []
|
2013-12-26 08:56:53 +00:00
|
|
|
self.is_new = True
|
|
|
|
for item in temp_service_items:
|
2013-08-31 18:17:38 +00:00
|
|
|
self.add_service_item(item['service_item'], False, expand=item['expanded'], repaint=False,
|
2013-12-26 08:56:53 +00:00
|
|
|
selected=item['selected'])
|
2013-03-29 12:53:07 +00:00
|
|
|
# Set to False as items may have changed rendering does not impact the saved song so True may also be valid
|
2012-04-02 15:33:54 +00:00
|
|
|
if changed:
|
2013-01-27 07:36:04 +00:00
|
|
|
self.set_modified()
|
2011-06-04 18:08:48 +00:00
|
|
|
# Repaint it once only at the end
|
2013-01-27 20:36:18 +00:00
|
|
|
self.repaint_service_list(-1, -1)
|
2013-02-03 19:23:12 +00:00
|
|
|
self.application.set_normal_cursor()
|
2009-04-23 18:22:54 +00:00
|
|
|
|
2013-12-30 19:50:34 +00:00
|
|
|
def replace_service_item(self, new_item):
|
2010-10-06 19:27:30 +00:00
|
|
|
"""
|
2013-03-29 12:53:07 +00:00
|
|
|
Using the service item passed replace the one with the same edit id if found.
|
2014-01-01 09:33:07 +00:00
|
|
|
|
|
|
|
:param new_item: a new service item to up date an existing one.
|
2010-10-06 19:27:30 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
for item_count, item in enumerate(self.service_items):
|
2013-12-30 19:50:34 +00:00
|
|
|
if item['service_item'].edit_id == new_item.edit_id and item['service_item'].name == new_item.name:
|
|
|
|
new_item.render()
|
|
|
|
new_item.merge(item['service_item'])
|
|
|
|
item['service_item'] = new_item
|
2013-01-27 20:36:18 +00:00
|
|
|
self.repaint_service_list(item_count + 1, 0)
|
2013-12-30 19:50:34 +00:00
|
|
|
self.live_controller.replace_service_manager_item(new_item)
|
2013-01-27 07:36:04 +00:00
|
|
|
self.set_modified()
|
2010-10-06 19:27:30 +00:00
|
|
|
|
2014-10-29 21:04:17 +00:00
|
|
|
def add_service_item(self, item, rebuild=False, expand=None, replace=False, repaint=True, selected=False,
|
|
|
|
position=-1):
|
2009-06-08 19:03:16 +00:00
|
|
|
"""
|
2009-08-06 17:43:53 +00:00
|
|
|
Add a Service item to the list
|
|
|
|
|
2014-01-01 09:33:07 +00:00
|
|
|
:param item: Service Item to be added
|
|
|
|
:param rebuild: Do we need to rebuild the live display (Default False)
|
|
|
|
:param expand: Override the default expand settings. (Tristate)
|
|
|
|
:param replace: Is the service item a replacement (Default False)
|
|
|
|
:param repaint: Do we need to repaint the service item list (Default True)
|
|
|
|
:param selected: Has the item been selected (Default False)
|
2014-10-29 21:04:17 +00:00
|
|
|
:param position: The position where the item is dropped (Default -1)
|
2009-06-08 19:03:16 +00:00
|
|
|
"""
|
2010-11-19 18:05:49 +00:00
|
|
|
# if not passed set to config value
|
|
|
|
if expand is None:
|
2013-08-31 18:17:38 +00:00
|
|
|
expand = Settings().value('advanced/expand service item')
|
2011-03-23 21:08:24 +00:00
|
|
|
item.from_service = True
|
2015-01-18 21:44:34 +00:00
|
|
|
if position != -1:
|
|
|
|
self.drop_position = position
|
2010-04-20 22:00:55 +00:00
|
|
|
if replace:
|
2014-01-01 09:33:07 +00:00
|
|
|
s_item, child = self.find_service_item()
|
|
|
|
item.merge(self.service_items[s_item]['service_item'])
|
|
|
|
self.service_items[s_item]['service_item'] = item
|
|
|
|
self.repaint_service_list(s_item, child)
|
2013-06-16 07:54:16 +00:00
|
|
|
self.live_controller.replace_service_manager_item(item)
|
2009-10-29 09:18:26 +00:00
|
|
|
else:
|
2011-10-02 19:57:42 +00:00
|
|
|
item.render()
|
2010-09-30 05:12:06 +00:00
|
|
|
# nothing selected for dnd
|
2014-10-29 21:04:17 +00:00
|
|
|
if self.drop_position == -1:
|
2010-03-27 20:27:33 +00:00
|
|
|
if isinstance(item, list):
|
2014-01-01 09:33:07 +00:00
|
|
|
for ind_item in item:
|
|
|
|
self.service_items.append({'service_item': ind_item,
|
2013-12-26 08:56:53 +00:00
|
|
|
'order': len(self.service_items) + 1,
|
|
|
|
'expanded': expand, 'selected': selected})
|
2010-03-27 20:27:33 +00:00
|
|
|
else:
|
2013-08-31 18:17:38 +00:00
|
|
|
self.service_items.append({'service_item': item,
|
2013-12-26 08:56:53 +00:00
|
|
|
'order': len(self.service_items) + 1,
|
|
|
|
'expanded': expand, 'selected': selected})
|
2011-04-29 08:45:36 +00:00
|
|
|
if repaint:
|
2013-01-27 20:36:18 +00:00
|
|
|
self.repaint_service_list(len(self.service_items) - 1, -1)
|
2009-10-29 09:18:26 +00:00
|
|
|
else:
|
2013-01-27 07:36:04 +00:00
|
|
|
self.service_items.insert(self.drop_position,
|
2013-12-30 19:50:34 +00:00
|
|
|
{'service_item': item, 'order': self.drop_position,
|
|
|
|
'expanded': expand, 'selected': selected})
|
2013-01-27 20:36:18 +00:00
|
|
|
self.repaint_service_list(self.drop_position, -1)
|
2010-09-30 05:12:06 +00:00
|
|
|
# if rebuilding list make sure live is fixed.
|
2010-02-22 06:14:44 +00:00
|
|
|
if rebuild:
|
2013-06-16 07:54:16 +00:00
|
|
|
self.live_controller.replace_service_manager_item(item)
|
2014-10-29 21:04:17 +00:00
|
|
|
self.drop_position = -1
|
2013-01-27 07:36:04 +00:00
|
|
|
self.set_modified()
|
2009-05-09 07:01:33 +00:00
|
|
|
|
2014-11-10 08:48:22 +00:00
|
|
|
def make_preview(self, field=None):
|
2009-06-08 19:03:16 +00:00
|
|
|
"""
|
|
|
|
Send the current item to the Preview slide controller
|
2014-11-10 08:48:22 +00:00
|
|
|
:param field:
|
2009-06-08 19:03:16 +00:00
|
|
|
"""
|
2013-02-03 19:23:12 +00:00
|
|
|
self.application.set_busy_cursor()
|
2013-01-27 07:36:04 +00:00
|
|
|
item, child = self.find_service_item()
|
2013-08-31 18:17:38 +00:00
|
|
|
if self.service_items[item]['service_item'].is_valid:
|
|
|
|
self.preview_controller.add_service_manager_item(self.service_items[item]['service_item'], child)
|
2010-05-06 16:49:12 +00:00
|
|
|
else:
|
2012-12-10 18:04:58 +00:00
|
|
|
critical_error_message_box(translate('OpenLP.ServiceManager', 'Missing Display Handler'),
|
2013-12-24 21:24:52 +00:00
|
|
|
translate('OpenLP.ServiceManager',
|
|
|
|
'Your item cannot be displayed as there is no handler to display it'))
|
2013-02-03 19:23:12 +00:00
|
|
|
self.application.set_normal_cursor()
|
2009-05-13 19:47:25 +00:00
|
|
|
|
2013-01-27 20:36:18 +00:00
|
|
|
def get_service_item(self):
|
2010-03-16 20:22:28 +00:00
|
|
|
"""
|
|
|
|
Send the current item to the Preview slide controller
|
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
item = self.find_service_item()[0]
|
2010-03-16 20:22:28 +00:00
|
|
|
if item == -1:
|
|
|
|
return False
|
|
|
|
else:
|
2013-08-31 18:17:38 +00:00
|
|
|
return self.service_items[item]['service_item']
|
2010-02-26 12:18:01 +00:00
|
|
|
|
2016-01-19 06:52:23 +00:00
|
|
|
def on_double_click_live(self, field=None):
|
2011-03-25 06:13:42 +00:00
|
|
|
"""
|
2013-03-29 12:53:07 +00:00
|
|
|
Send the current item to the Live slide controller but triggered by a tablewidget click event.
|
2014-01-01 09:33:07 +00:00
|
|
|
:param field:
|
2011-03-25 06:13:42 +00:00
|
|
|
"""
|
2016-01-19 06:52:23 +00:00
|
|
|
self.list_double_clicked = True
|
2013-01-27 07:36:04 +00:00
|
|
|
self.make_live()
|
2011-03-25 06:13:42 +00:00
|
|
|
|
2016-01-17 16:46:37 +00:00
|
|
|
def on_single_click_preview(self, field=None):
|
|
|
|
"""
|
2016-01-19 07:02:47 +00:00
|
|
|
If single click previewing is enabled, and triggered by a tablewidget click event,
|
|
|
|
start a timeout to verify a double-click hasn't triggered.
|
2016-01-17 16:46:37 +00:00
|
|
|
:param field:
|
|
|
|
"""
|
|
|
|
if Settings().value('advanced/single click service preview'):
|
2016-01-19 06:52:23 +00:00
|
|
|
if not self.list_double_clicked:
|
|
|
|
# If a double click has not registered start a timer, otherwise wait for the existing timer to finish.
|
2016-01-19 07:02:47 +00:00
|
|
|
QtCore.QTimer.singleShot(QtWidgets.QApplication.instance().doubleClickInterval(),
|
|
|
|
self.on_single_click_preview_timeout)
|
|
|
|
|
2016-01-19 06:52:23 +00:00
|
|
|
def on_single_click_preview_timeout(self):
|
|
|
|
"""
|
2016-01-19 07:02:47 +00:00
|
|
|
If a single click ok, but double click not triggered, send the current item to the Preview slide controller.
|
2016-01-19 06:52:23 +00:00
|
|
|
:param field:
|
|
|
|
"""
|
|
|
|
if self.list_double_clicked:
|
|
|
|
# If a double click has registered, clear it.
|
|
|
|
self.list_double_clicked = False
|
|
|
|
else:
|
|
|
|
# Otherwise preview the item.
|
2016-01-17 16:46:37 +00:00
|
|
|
self.make_preview()
|
|
|
|
|
2013-01-27 07:36:04 +00:00
|
|
|
def make_live(self, row=-1):
|
2009-06-08 19:03:16 +00:00
|
|
|
"""
|
|
|
|
Send the current item to the Live slide controller
|
2011-03-23 21:08:24 +00:00
|
|
|
|
2014-01-01 09:33:07 +00:00
|
|
|
:param row: Row number to be displayed if from preview. -1 is passed if the value is not set
|
2009-06-08 19:03:16 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
item, child = self.find_service_item()
|
2011-04-02 09:52:32 +00:00
|
|
|
# No items in service
|
|
|
|
if item == -1:
|
|
|
|
return
|
2011-03-23 21:08:24 +00:00
|
|
|
if row != -1:
|
|
|
|
child = row
|
2013-02-03 19:23:12 +00:00
|
|
|
self.application.set_busy_cursor()
|
2013-08-31 18:17:38 +00:00
|
|
|
if self.service_items[item]['service_item'].is_valid:
|
|
|
|
self.live_controller.add_service_manager_item(self.service_items[item]['service_item'], child)
|
|
|
|
if Settings().value(self.main_window.general_settings_section + '/auto preview'):
|
2010-05-04 20:01:45 +00:00
|
|
|
item += 1
|
2013-01-27 07:36:04 +00:00
|
|
|
if self.service_items and item < len(self.service_items) and \
|
2013-08-31 18:17:38 +00:00
|
|
|
self.service_items[item]['service_item'].is_capable(ItemCapabilities.CanPreview):
|
|
|
|
self.preview_controller.add_service_manager_item(self.service_items[item]['service_item'], 0)
|
2013-04-18 20:15:44 +00:00
|
|
|
self.live_controller.preview_widget.setFocus()
|
2010-05-04 20:01:45 +00:00
|
|
|
else:
|
2012-12-10 18:04:58 +00:00
|
|
|
critical_error_message_box(translate('OpenLP.ServiceManager', 'Missing Display Handler'),
|
2013-12-24 15:55:01 +00:00
|
|
|
translate('OpenLP.ServiceManager',
|
|
|
|
'Your item cannot be displayed as the plugin required to display it '
|
|
|
|
'is missing or inactive'))
|
2013-02-21 17:30:18 +00:00
|
|
|
self.application.set_normal_cursor()
|
2009-05-14 18:00:36 +00:00
|
|
|
|
2013-12-31 20:29:03 +00:00
|
|
|
def remote_edit(self, field=None):
|
2009-10-29 09:18:26 +00:00
|
|
|
"""
|
2013-01-27 09:57:03 +00:00
|
|
|
Triggers a remote edit to a plugin to allow item to be edited.
|
2014-01-01 09:33:07 +00:00
|
|
|
:param field:
|
2009-10-29 09:18:26 +00:00
|
|
|
"""
|
2013-02-01 20:40:23 +00:00
|
|
|
item = self.find_service_item()[0]
|
2013-08-31 18:17:38 +00:00
|
|
|
if self.service_items[item]['service_item'].is_capable(ItemCapabilities.CanEdit):
|
|
|
|
new_item = Registry().get(self.service_items[item]['service_item'].name). \
|
|
|
|
on_remote_edit(self.service_items[item]['service_item'].edit_id)
|
2013-01-27 09:57:03 +00:00
|
|
|
if new_item:
|
2013-01-27 20:36:18 +00:00
|
|
|
self.add_service_item(new_item, replace=True)
|
2009-10-29 09:18:26 +00:00
|
|
|
|
2014-04-14 19:07:01 +00:00
|
|
|
def on_service_item_rename(self, field=None):
|
2013-04-02 10:19:33 +00:00
|
|
|
"""
|
|
|
|
Opens a dialog to rename the service item.
|
2014-04-14 19:07:01 +00:00
|
|
|
|
|
|
|
:param field: Not used, but PyQt needs this.
|
2013-04-02 10:19:33 +00:00
|
|
|
"""
|
|
|
|
item = self.find_service_item()[0]
|
2013-09-05 07:23:59 +00:00
|
|
|
if not self.service_items[item]['service_item'].is_capable(ItemCapabilities.CanEditTitle):
|
2013-04-02 19:28:56 +00:00
|
|
|
return
|
2013-09-05 07:23:59 +00:00
|
|
|
title = self.service_items[item]['service_item'].title
|
2015-11-07 00:49:40 +00:00
|
|
|
title, ok = QtWidgets.QInputDialog.getText(self, translate('OpenLP.ServiceManager', 'Rename item title'),
|
|
|
|
translate('OpenLP.ServiceManager', 'Title:'),
|
|
|
|
QtWidgets.QLineEdit.Normal, self.tr(title))
|
2013-04-02 10:19:33 +00:00
|
|
|
if ok:
|
2013-09-10 20:29:45 +00:00
|
|
|
self.service_items[item]['service_item'].title = title
|
2013-04-02 10:19:33 +00:00
|
|
|
self.repaint_service_list(item, -1)
|
|
|
|
self.set_modified()
|
|
|
|
|
2013-12-31 20:29:03 +00:00
|
|
|
def create_custom(self, field=None):
|
2012-12-23 00:00:24 +00:00
|
|
|
"""
|
|
|
|
Saves the current text item as a custom slide
|
2014-01-01 09:33:07 +00:00
|
|
|
:param field:
|
2012-12-23 00:00:24 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
item = self.find_service_item()[0]
|
2013-08-31 18:17:38 +00:00
|
|
|
Registry().execute('custom_create_from_service', self.service_items[item]['service_item'])
|
2012-12-23 00:00:24 +00:00
|
|
|
|
2013-01-27 07:36:04 +00:00
|
|
|
def find_service_item(self):
|
2009-06-08 19:03:16 +00:00
|
|
|
"""
|
2014-03-20 19:10:31 +00:00
|
|
|
Finds the first selected ServiceItem in the list and returns the position of the service_item_from_item and its
|
|
|
|
selected child item. For example, if the third child item (in the Slidecontroller known as slide) in the
|
|
|
|
second service item is selected this will return::
|
2011-01-20 16:12:07 +00:00
|
|
|
|
|
|
|
(1, 2)
|
2009-06-08 19:03:16 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
items = self.service_manager_list.selectedItems()
|
2013-03-06 22:23:01 +00:00
|
|
|
service_item = -1
|
|
|
|
service_item_child = -1
|
2009-05-14 18:00:36 +00:00
|
|
|
for item in items:
|
2013-01-21 07:29:43 +00:00
|
|
|
parent_item = item.parent()
|
|
|
|
if parent_item is None:
|
2013-03-06 22:23:01 +00:00
|
|
|
service_item = item.data(0, QtCore.Qt.UserRole)
|
2009-05-14 18:00:36 +00:00
|
|
|
else:
|
2013-03-06 22:23:01 +00:00
|
|
|
service_item = parent_item.data(0, QtCore.Qt.UserRole)
|
|
|
|
service_item_child = item.data(0, QtCore.Qt.UserRole)
|
2012-05-07 08:21:21 +00:00
|
|
|
# Adjust for zero based arrays.
|
2013-03-06 22:23:01 +00:00
|
|
|
service_item -= 1
|
2012-05-07 08:21:21 +00:00
|
|
|
# Only process the first item on the list for this method.
|
|
|
|
break
|
2013-03-06 22:23:01 +00:00
|
|
|
return service_item, service_item_child
|
2009-05-12 21:06:35 +00:00
|
|
|
|
2013-01-27 07:36:04 +00:00
|
|
|
def drop_event(self, event):
|
2009-05-09 07:01:33 +00:00
|
|
|
"""
|
2013-03-29 12:53:07 +00:00
|
|
|
Receive drop event and trigger an internal event to get the plugins to build and push the correct service item.
|
2009-08-06 17:43:53 +00:00
|
|
|
The drag event payload carries the plugin name
|
|
|
|
|
2014-01-01 09:33:07 +00:00
|
|
|
:param event: Handle of the event passed
|
2009-05-09 07:01:33 +00:00
|
|
|
"""
|
2009-05-22 18:30:25 +00:00
|
|
|
link = event.mimeData()
|
2012-03-12 22:12:16 +00:00
|
|
|
if link.hasUrls():
|
2011-07-27 18:28:35 +00:00
|
|
|
event.setDropAction(QtCore.Qt.CopyAction)
|
|
|
|
event.accept()
|
2012-03-12 22:12:16 +00:00
|
|
|
for url in link.urls():
|
2013-01-27 07:36:04 +00:00
|
|
|
file_name = url.toLocalFile()
|
2013-08-31 18:17:38 +00:00
|
|
|
if file_name.endswith('.osz'):
|
2013-01-27 07:36:04 +00:00
|
|
|
self.on_load_service_clicked(file_name)
|
2013-08-31 18:17:38 +00:00
|
|
|
elif file_name.endswith('.oszl'):
|
2012-09-14 16:35:07 +00:00
|
|
|
# todo correct
|
2013-01-27 07:36:04 +00:00
|
|
|
self.on_load_service_clicked(file_name)
|
2012-03-12 22:12:16 +00:00
|
|
|
elif link.hasText():
|
2012-05-17 18:57:01 +00:00
|
|
|
plugin = link.text()
|
2013-01-27 07:36:04 +00:00
|
|
|
item = self.service_manager_list.itemAt(event.pos())
|
2010-09-30 05:12:06 +00:00
|
|
|
# ServiceManager started the drag and drop
|
2013-08-31 18:17:38 +00:00
|
|
|
if plugin == 'ServiceManager':
|
2013-12-26 08:56:53 +00:00
|
|
|
start_pos, child = self.find_service_item()
|
2010-11-28 13:41:52 +00:00
|
|
|
# If no items selected
|
2013-12-26 08:56:53 +00:00
|
|
|
if start_pos == -1:
|
2010-11-28 13:41:52 +00:00
|
|
|
return
|
2010-02-27 00:11:26 +00:00
|
|
|
if item is None:
|
2017-10-08 20:36:11 +00:00
|
|
|
end_pos = len(self.service_items) - 1
|
2009-10-11 09:31:27 +00:00
|
|
|
else:
|
2016-01-07 13:10:31 +00:00
|
|
|
end_pos = get_parent_item_data(item) - 1
|
2013-12-26 08:56:53 +00:00
|
|
|
service_item = self.service_items[start_pos]
|
2017-10-08 20:36:11 +00:00
|
|
|
if start_pos != end_pos:
|
|
|
|
self.service_items.remove(service_item)
|
|
|
|
self.service_items.insert(end_pos, service_item)
|
|
|
|
self.repaint_service_list(end_pos, child)
|
|
|
|
self.set_modified()
|
2009-10-11 09:31:27 +00:00
|
|
|
else:
|
2010-09-30 05:12:06 +00:00
|
|
|
# we are not over anything so drop
|
2010-05-01 13:05:17 +00:00
|
|
|
replace = False
|
2010-06-09 17:09:32 +00:00
|
|
|
if item is None:
|
2013-01-27 07:36:04 +00:00
|
|
|
self.drop_position = len(self.service_items)
|
2010-03-14 07:56:39 +00:00
|
|
|
else:
|
2011-03-06 07:59:26 +00:00
|
|
|
# we are over something so lets investigate
|
2016-01-07 13:10:31 +00:00
|
|
|
pos = get_parent_item_data(item) - 1
|
2013-12-26 08:56:53 +00:00
|
|
|
service_item = self.service_items[pos]
|
|
|
|
if (plugin == service_item['service_item'].name and
|
|
|
|
service_item['service_item'].is_capable(ItemCapabilities.CanAppend)):
|
2015-11-07 00:49:40 +00:00
|
|
|
action = self.dnd_menu.exec(QtGui.QCursor.pos())
|
2010-09-30 05:12:06 +00:00
|
|
|
# New action required
|
2013-12-26 08:56:53 +00:00
|
|
|
if action == self.new_action:
|
2016-01-07 13:10:31 +00:00
|
|
|
self.drop_position = get_parent_item_data(item)
|
2010-09-30 05:12:06 +00:00
|
|
|
# Append to existing action
|
2013-12-26 08:56:53 +00:00
|
|
|
if action == self.add_to_action:
|
2016-01-07 13:10:31 +00:00
|
|
|
self.drop_position = get_parent_item_data(item)
|
2010-05-24 22:37:20 +00:00
|
|
|
item.setSelected(True)
|
|
|
|
replace = True
|
2010-05-01 13:05:17 +00:00
|
|
|
else:
|
2016-01-07 13:10:31 +00:00
|
|
|
self.drop_position = get_parent_item_data(item) - 1
|
2016-05-20 16:22:06 +00:00
|
|
|
Registry().execute('{plugin}_add_service_item'.format(plugin=plugin), replace)
|
2009-03-04 21:55:24 +00:00
|
|
|
|
2013-01-27 07:36:04 +00:00
|
|
|
def update_theme_list(self, theme_list):
|
2009-05-09 07:01:33 +00:00
|
|
|
"""
|
|
|
|
Called from ThemeManager when the Themes have changed
|
2009-08-06 17:43:53 +00:00
|
|
|
|
2014-01-01 09:33:07 +00:00
|
|
|
:param theme_list: A list of current themes to be displayed
|
2009-05-09 07:01:33 +00:00
|
|
|
"""
|
2013-01-27 07:36:04 +00:00
|
|
|
self.theme_combo_box.clear()
|
|
|
|
self.theme_menu.clear()
|
2013-08-31 18:17:38 +00:00
|
|
|
self.theme_combo_box.addItem('')
|
2015-11-07 00:49:40 +00:00
|
|
|
theme_group = QtWidgets.QActionGroup(self.theme_menu)
|
2013-01-27 07:36:04 +00:00
|
|
|
theme_group.setExclusive(True)
|
2013-08-31 18:17:38 +00:00
|
|
|
theme_group.setObjectName('theme_group')
|
2013-03-29 12:53:07 +00:00
|
|
|
# Create a "Default" theme, which allows the user to reset the item's theme to the service theme or global
|
|
|
|
# theme.
|
2013-12-26 08:56:53 +00:00
|
|
|
default_theme = create_widget_action(self.theme_menu, text=UiStrings().Default, checked=False,
|
|
|
|
triggers=self.on_theme_change_action)
|
|
|
|
self.theme_menu.setDefaultAction(default_theme)
|
|
|
|
theme_group.addAction(default_theme)
|
2013-01-27 07:36:04 +00:00
|
|
|
self.theme_menu.addSeparator()
|
2009-04-23 18:22:54 +00:00
|
|
|
for theme in theme_list:
|
2013-01-27 07:36:04 +00:00
|
|
|
self.theme_combo_box.addItem(theme)
|
|
|
|
theme_group.addAction(create_widget_action(self.theme_menu, theme, text=theme, checked=False,
|
2013-12-24 15:55:01 +00:00
|
|
|
triggers=self.on_theme_change_action))
|
2013-01-27 07:36:04 +00:00
|
|
|
find_and_set_in_combo_box(self.theme_combo_box, self.service_theme)
|
2013-01-22 21:09:43 +00:00
|
|
|
self.renderer.set_service_theme(self.service_theme)
|
2013-12-26 08:56:53 +00:00
|
|
|
self.regenerate_service_items()
|
2009-10-25 16:26:03 +00:00
|
|
|
|
2013-12-31 20:29:03 +00:00
|
|
|
def on_theme_change_action(self, field=None):
|
2013-01-21 17:22:10 +00:00
|
|
|
"""
|
|
|
|
Handles theme change events
|
2014-01-01 09:33:07 +00:00
|
|
|
|
|
|
|
:param field:
|
2013-01-21 17:22:10 +00:00
|
|
|
"""
|
2012-05-17 18:57:01 +00:00
|
|
|
theme = self.sender().objectName()
|
2011-05-27 06:29:14 +00:00
|
|
|
# No object name means that the "Default" theme is supposed to be used.
|
|
|
|
if not theme:
|
|
|
|
theme = None
|
2013-01-27 07:36:04 +00:00
|
|
|
item = self.find_service_item()[0]
|
2013-08-31 18:17:38 +00:00
|
|
|
self.service_items[item]['service_item'].update_theme(theme)
|
2013-12-26 08:56:53 +00:00
|
|
|
self.regenerate_service_items(True)
|
2010-03-14 17:05:50 +00:00
|
|
|
|
2017-11-13 21:31:54 +00:00
|
|
|
def on_make_live_action_triggered(self, checked):
|
|
|
|
"""
|
|
|
|
Handle `make_live_action` when the action is triggered.
|
|
|
|
|
|
|
|
:param bool checked: Not Used.
|
|
|
|
:rtype: None
|
|
|
|
"""
|
|
|
|
self.make_live()
|
|
|
|
|
2014-10-29 21:04:17 +00:00
|
|
|
def get_drop_position(self):
|
|
|
|
"""
|
|
|
|
Getter for drop_position. Used in: MediaManagerItem
|
|
|
|
"""
|
|
|
|
return self.drop_position
|
2016-01-05 22:28:48 +00:00
|
|
|
|
|
|
|
|
2016-01-07 13:10:31 +00:00
|
|
|
def get_parent_item_data(item):
|
2016-01-05 22:28:48 +00:00
|
|
|
"""
|
|
|
|
Finds and returns the parent item for any item
|
|
|
|
|
|
|
|
:param item: The service item list item to be checked.
|
|
|
|
"""
|
|
|
|
parent_item = item.parent()
|
|
|
|
if parent_item is None:
|
|
|
|
return item.data(0, QtCore.Qt.UserRole)
|
|
|
|
else:
|
|
|
|
return parent_item.data(0, QtCore.Qt.UserRole)
|