diff --git a/openlp/core/ui/advancedtab.py b/openlp/core/ui/advancedtab.py index 7c522bc67..210dabdd2 100644 --- a/openlp/core/ui/advancedtab.py +++ b/openlp/core/ui/advancedtab.py @@ -27,6 +27,8 @@ """ The :mod:`advancedtab` provides an advanced settings facility. """ +from datetime import datetime, timedelta + from PyQt4 import QtCore, QtGui from openlp.core.lib import SettingsTab, translate, build_icon, Receiver @@ -43,12 +45,26 @@ class AdvancedTab(SettingsTab): """ Initialise the settings tab """ - self.display_changed = False - advancedTranslated = translate('OpenLP.AdvancedTab', 'Advanced') - self.default_image = u':/graphics/openlp-splash-screen.png' - self.default_color = u'#ffffff' + self.displayChanged = False + # 7 stands for now, 0 to 6 is Monday to Sunday. + self.defaultServiceDay = 7 + # 11 o'clock is the most popular time for morning service. + self.defaultServiceHour = 11 + self.defaultServiceMinute = 0 + self.defaultServiceName = unicode(translate('OpenLP.AdvancedTab', + 'Service %Y-%m-%d %H-%M', + 'This is the default default service name template, which can be ' + 'found under Advanced in Settings, Configure OpenLP. Please do not ' + 'include any of the following characters: /\\?*|<>\[\]":+\n' + 'You can use any of the directives as shown on page ' + 'http://docs.python.org/library/datetime.html' + '#strftime-strptime-behavior , but if possible, please keep ' + 'the resulting string sortable by name.')) + self.defaultImage = u':/graphics/openlp-splash-screen.png' + self.defaultColor = u'#ffffff' self.icon_path = u':/system/system_settings.png' - SettingsTab.__init__(self, parent, u'Advanced', advancedTranslated) + advanced_translated = translate('OpenLP.AdvancedTab', 'Advanced') + SettingsTab.__init__(self, parent, u'Advanced', advanced_translated) def setupUi(self): """ @@ -85,6 +101,61 @@ class AdvancedTab(SettingsTab): u'enableAutoCloseCheckBox') self.uiLayout.addRow(self.enableAutoCloseCheckBox) self.leftLayout.addWidget(self.uiGroupBox) + # Default service name + self.serviceNameGroupBox = QtGui.QGroupBox(self.leftColumn) + self.serviceNameGroupBox.setObjectName(u'serviceNameGroupBox') + self.serviceNameLayout = QtGui.QFormLayout( + self.serviceNameGroupBox) + self.serviceNameCheckBox = QtGui.QCheckBox( + self.serviceNameGroupBox) + self.serviceNameCheckBox.setObjectName(u'serviceNameCheckBox') + self.serviceNameLayout.setObjectName(u'serviceNameLayout') + self.serviceNameLayout.addRow(self.serviceNameCheckBox) + self.serviceNameTimeLabel = QtGui.QLabel(self.serviceNameGroupBox) + self.serviceNameTimeLabel.setObjectName(u'serviceNameTimeLabel') + self.serviceNameDay = QtGui.QComboBox( + self.serviceNameGroupBox) + self.serviceNameDay.addItems( + [u'', u'', u'', u'', u'', u'', u'', u'']) + self.serviceNameDay.setObjectName( + u'serviceNameDay') + self.serviceNameTime = QtGui.QTimeEdit(self.serviceNameGroupBox) + self.serviceNameTime.setObjectName(u'serviceNameTime') + self.serviceNameTimeHBox = QtGui.QHBoxLayout() + self.serviceNameTimeHBox.setObjectName(u'serviceNameTimeHBox') + self.serviceNameTimeHBox.addWidget(self.serviceNameDay) + self.serviceNameTimeHBox.addWidget(self.serviceNameTime) + self.serviceNameLayout.addRow(self.serviceNameTimeLabel, + self.serviceNameTimeHBox) + self.serviceNameLabel = QtGui.QLabel(self.serviceNameGroupBox) + self.serviceNameLabel.setObjectName(u'serviceNameLabel') + self.serviceNameEdit = QtGui.QLineEdit(self.serviceNameGroupBox) + self.serviceNameEdit.setObjectName(u'serviceNameEdit') + self.serviceNameEdit.setValidator(QtGui.QRegExpValidator( + QtCore.QRegExp(r'[^/\\?*|<>\[\]":+]+'), self)) + self.serviceNameRevertButton = QtGui.QToolButton( + self.serviceNameGroupBox) + self.serviceNameRevertButton.setObjectName( + u'serviceNameRevertButton') + self.serviceNameRevertButton.setIcon( + build_icon(u':/general/general_revert.png')) + self.serviceNameHBox = QtGui.QHBoxLayout() + self.serviceNameHBox.setObjectName(u'serviceNameHBox') + self.serviceNameHBox.addWidget(self.serviceNameEdit) + self.serviceNameHBox.addWidget(self.serviceNameRevertButton) + self.serviceNameLayout.addRow(self.serviceNameLabel, + self.serviceNameHBox) + self.serviceNameExampleLabel = QtGui.QLabel( + self.serviceNameGroupBox) + self.serviceNameExampleLabel.setObjectName( + u'serviceNameExampleLabel') + self.serviceNameExample = QtGui.QLabel(self.serviceNameGroupBox) + self.serviceNameExample.setObjectName(u'serviceNameExample') + self.serviceNameLayout.addRow(self.serviceNameExampleLabel, + self.serviceNameExample) + self.leftLayout.addWidget(self.serviceNameGroupBox) + self.leftLayout.addStretch() + # Default Image self.defaultImageGroupBox = QtGui.QGroupBox(self.rightColumn) self.defaultImageGroupBox.setObjectName(u'defaultImageGroupBox') self.defaultImageLayout = QtGui.QFormLayout(self.defaultImageGroupBox) @@ -114,16 +185,16 @@ class AdvancedTab(SettingsTab): self.defaultFileLayout.addWidget(self.defaultRevertButton) self.defaultImageLayout.addRow(self.defaultFileLabel, self.defaultFileLayout) - self.leftLayout.addWidget(self.defaultImageGroupBox) - self.hideMouseGroupBox = QtGui.QGroupBox(self.leftColumn) + self.rightLayout.addWidget(self.defaultImageGroupBox) + # Hide mouse + self.hideMouseGroupBox = QtGui.QGroupBox(self.rightColumn) self.hideMouseGroupBox.setObjectName(u'hideMouseGroupBox') self.hideMouseLayout = QtGui.QVBoxLayout(self.hideMouseGroupBox) self.hideMouseLayout.setObjectName(u'hideMouseLayout') self.hideMouseCheckBox = QtGui.QCheckBox(self.hideMouseGroupBox) self.hideMouseCheckBox.setObjectName(u'hideMouseCheckBox') self.hideMouseLayout.addWidget(self.hideMouseCheckBox) - self.leftLayout.addWidget(self.hideMouseGroupBox) - self.leftLayout.addStretch() + self.rightLayout.addWidget(self.hideMouseGroupBox) # Service Item Slide Limits self.slideGroupBox = QtGui.QGroupBox(self.rightColumn) self.slideGroupBox.setObjectName(u'slideGroupBox') @@ -165,6 +236,21 @@ class AdvancedTab(SettingsTab): self.rightLayout.addWidget(self.x11GroupBox) self.rightLayout.addStretch() + self.shouldUpdateServiceNameExample = False + QtCore.QObject.connect(self.serviceNameCheckBox, + QtCore.SIGNAL(u'toggled(bool)'), self.serviceNameCheckBoxToggled) + QtCore.QObject.connect(self.serviceNameDay, + QtCore.SIGNAL(u'currentIndexChanged(int)'), + self.onServiceNameDayChanged) + QtCore.QObject.connect(self.serviceNameTime, + QtCore.SIGNAL(u'timeChanged(QTime)'), + self.updateServiceNameExample) + QtCore.QObject.connect(self.serviceNameEdit, + QtCore.SIGNAL(u'textChanged(QString)'), + self.updateServiceNameExample) + QtCore.QObject.connect(self.serviceNameRevertButton, + QtCore.SIGNAL(u'pressed()'), + self.onServiceNameRevertButtonPressed) QtCore.QObject.connect(self.defaultColorButton, QtCore.SIGNAL(u'pressed()'), self.onDefaultColorButtonPressed) QtCore.QObject.connect(self.defaultBrowseButton, @@ -200,6 +286,40 @@ class AdvancedTab(SettingsTab): 'Expand new service items on creation')) self.enableAutoCloseCheckBox.setText(translate('OpenLP.AdvancedTab', 'Enable application exit confirmation')) + self.serviceNameGroupBox.setTitle( + translate('OpenLP.AdvancedTab', 'Default Service Name')) + self.serviceNameCheckBox.setText( + translate('OpenLP.AdvancedTab', 'Enable default service name')) + self.serviceNameTimeLabel.setText( + translate('OpenLP.AdvancedTab', 'Date and Time:')) + self.serviceNameDay.setItemText(0, + translate('OpenLP.AdvancedTab', 'Monday')) + self.serviceNameDay.setItemText(1, + translate('OpenLP.AdvancedTab', 'Tuesday')) + self.serviceNameDay.setItemText(2, + translate('OpenLP.AdvancedTab', 'Wednesday')) + self.serviceNameDay.setItemText(3, + translate('OpenLP.AdvancedTab', 'Thurdsday')) + self.serviceNameDay.setItemText(4, + translate('OpenLP.AdvancedTab', 'Friday')) + self.serviceNameDay.setItemText(5, + translate('OpenLP.AdvancedTab', 'Saturday')) + self.serviceNameDay.setItemText(6, + translate('OpenLP.AdvancedTab', 'Sunday')) + self.serviceNameDay.setItemText(7, + translate('OpenLP.AdvancedTab', 'Now')) + self.serviceNameTime.setToolTip(translate('OpenLP.AdvancedTab', + 'Time when usual service starts.')) + self.serviceNameLabel.setText( + translate('OpenLP.AdvancedTab', 'Name:')) + self.serviceNameEdit.setToolTip(translate('OpenLP.AdvancedTab', + 'Consult the OpenLP manual for usage.')) + self.serviceNameRevertButton.setToolTip(unicode( + translate('OpenLP.AdvancedTab', + 'Revert to the default service name "%s".')) % + self.defaultServiceName) + self.serviceNameExampleLabel.setText(translate('OpenLP.AdvancedTab', + 'Example:')) self.hideMouseGroupBox.setTitle(translate('OpenLP.AdvancedTab', 'Mouse Cursor')) self.hideMouseCheckBox.setText(translate('OpenLP.AdvancedTab', @@ -270,9 +390,24 @@ class AdvancedTab(SettingsTab): QtCore.QVariant(True)).toBool()) self.hideMouseCheckBox.setChecked( settings.value(u'hide mouse', QtCore.QVariant(False)).toBool()) + self.serviceNameDay.setCurrentIndex( + settings.value(u'default service day', + QtCore.QVariant(self.defaultServiceDay)).toInt()[0]) + self.serviceNameTime.setTime(QtCore.QTime( + settings.value(u'default service hour', + self.defaultServiceHour).toInt()[0], + settings.value(u'default service minute', + self.defaultServiceMinute).toInt()[0])) + self.shouldUpdateServiceNameExample = True + self.serviceNameEdit.setText(settings.value(u'default service name', + self.defaultServiceName).toString()) + default_service_enabled = settings.value(u'default service enabled', + QtCore.QVariant(True)).toBool() + self.serviceNameCheckBox.setChecked(default_service_enabled) + self.serviceNameCheckBoxToggled(default_service_enabled) self.x11BypassCheckBox.setChecked( settings.value(u'x11 bypass wm', QtCore.QVariant(True)).toBool()) - self.default_color = settings.value(u'default color', + self.defaultColor = settings.value(u'default color', QtCore.QVariant(u'#ffffff')).toString() self.defaultFileEdit.setText(settings.value(u'default image', QtCore.QVariant(u':/graphics/openlp-splash-screen.png'))\ @@ -287,7 +422,7 @@ class AdvancedTab(SettingsTab): self.nextItemRadioButton.setChecked(True) settings.endGroup() self.defaultColorButton.setStyleSheet( - u'background-color: %s' % self.default_color) + u'background-color: %s' % self.defaultColor) def save(self): """ @@ -295,6 +430,21 @@ class AdvancedTab(SettingsTab): """ settings = QtCore.QSettings() settings.beginGroup(self.settingsSection) + settings.setValue(u'default service enabled', + self.serviceNameCheckBox.isChecked()) + service_name = unicode(self.serviceNameEdit.text()) + preset_is_valid = self.generateServiceNameExample()[0] + if service_name == self.defaultServiceName or not preset_is_valid: + settings.remove(u'default service name') + self.serviceNameEdit.setText(service_name) + else: + settings.setValue(u'default service name', service_name) + settings.setValue(u'default service day', + self.serviceNameDay.currentIndex()) + settings.setValue(u'default service hour', + self.serviceNameTime.time().hour()) + settings.setValue(u'default service minute', + self.serviceNameTime.time().minute()) settings.setValue(u'recent file count', QtCore.QVariant(self.recentSpinBox.value())) settings.setValue(u'save current plugin', @@ -311,22 +461,65 @@ class AdvancedTab(SettingsTab): QtCore.QVariant(self.hideMouseCheckBox.isChecked())) settings.setValue(u'x11 bypass wm', QtCore.QVariant(self.x11BypassCheckBox.isChecked())) - settings.setValue(u'default color', self.default_color) + settings.setValue(u'default color', self.defaultColor) settings.setValue(u'default image', self.defaultFileEdit.text()) settings.setValue(u'slide limits', QtCore.QVariant(self.slide_limits)) settings.endGroup() - if self.display_changed: + if self.displayChanged: Receiver.send_message(u'config_screen_changed') - self.display_changed = False + self.displayChanged = False Receiver.send_message(u'slidecontroller_update_slide_limits') + def serviceNameCheckBoxToggled(self, default_service_enabled): + self.serviceNameDay.setEnabled(default_service_enabled) + time_enabled = default_service_enabled and \ + self.serviceNameDay.currentIndex() is not 7 + self.serviceNameTime.setEnabled(time_enabled) + self.serviceNameEdit.setEnabled(default_service_enabled) + self.serviceNameRevertButton.setEnabled(default_service_enabled) + + def generateServiceNameExample(self): + preset_is_valid = True + if self.serviceNameDay.currentIndex() == 7: + time = datetime.now() + else: + now = datetime.now() + day_delta = self.serviceNameDay.currentIndex() - now.weekday() + if day_delta < 0: + day_delta += 7 + time = now + timedelta(days=day_delta) + time = time.replace(hour = self.serviceNameTime.time().hour(), + minute = self.serviceNameTime.time().minute()) + try: + service_name_example = time.strftime(unicode( + self.serviceNameEdit.text())) + except ValueError: + preset_is_valid = False + service_name_example = translate('OpenLP.AdvancedTab', + 'Syntax error.') + return preset_is_valid, service_name_example + + def updateServiceNameExample(self, returned_value): + if not self.shouldUpdateServiceNameExample: + return + name_example = self.generateServiceNameExample()[1] + self.serviceNameExample.setText(name_example) + + def onServiceNameDayChanged(self, service_day): + self.serviceNameTime.setEnabled(service_day is not 7) + self.updateServiceNameExample(None) + + def onServiceNameRevertButtonPressed(self): + self.serviceNameEdit.setText(self.defaultServiceName) + self.serviceNameEdit.setFocus() + def onDefaultColorButtonPressed(self): new_color = QtGui.QColorDialog.getColor( - QtGui.QColor(self.default_color), self) + QtGui.QColor(self.defaultColor), self) if new_color.isValid(): - self.default_color = new_color.name() + self.defaultColor = new_color.name() self.defaultColorButton.setStyleSheet( - u'background-color: %s' % self.default_color) + u'background-color: %s' % self.defaultColor) def onDefaultBrowseButtonPressed(self): file_filters = u'%s;;%s (*.*) (*)' % (get_images_filter(), @@ -349,7 +542,7 @@ class AdvancedTab(SettingsTab): ``checked`` The state of the check box (boolean). """ - self.display_changed = True + self.displayChanged = True def onEndSlideButtonPressed(self): self.slide_limits = SlideLimits.End diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index f2c4a7702..2217dc168 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -31,6 +31,7 @@ import os import shutil import zipfile from tempfile import mkstemp +from datetime import datetime, timedelta log = logging.getLogger(__name__) @@ -612,10 +613,44 @@ class ServiceManager(QtGui.QWidget): Get a file name and then call :func:`ServiceManager.saveFile` to save the file. """ + default_service_enabled = QtCore.QSettings().value( + u'advanced/default service enabled', QtCore.QVariant(True)).toBool() + if default_service_enabled: + service_day = QtCore.QSettings().value( + u'advanced/default service day', 7).toInt()[0] + if service_day == 7: + time = datetime.now() + else: + service_hour = QtCore.QSettings().value( + u'advanced/default service hour', 11).toInt()[0] + service_minute = QtCore.QSettings().value( + u'advanced/default service minute', 0).toInt()[0] + now = datetime.now() + day_delta = service_day - now.weekday() + if day_delta < 0: + day_delta += 7 + time = now + timedelta(days=day_delta) + time = time.replace(hour=service_hour, minute=service_minute) + default_pattern = unicode(QtCore.QSettings().value( + u'advanced/default service name', + translate('OpenLP.AdvancedTab', + 'Service %Y-%m-%d %H-%M', + 'This is the default default service name template, which can ' + 'be found under Advanced in Settings, Configure OpenLP. ' + 'Please do not include any of the following characters: ' + '/\\?*|<>\[\]":+\n' + 'You can use any of the directives as shown on page ' + 'http://docs.python.org/library/datetime.html' + '#strftime-strptime-behavior , but if possible, please keep ' + 'the resulting string sortable by name.')).toString()) + default_filename = time.strftime(default_pattern) + else: + default_filename = u'' + directory = unicode(SettingsManager.get_last_dir( + self.mainwindow.servicemanagerSettingsSection)) + path = os.path.join(directory, default_filename) fileName = unicode(QtGui.QFileDialog.getSaveFileName(self.mainwindow, - UiStrings().SaveService, - SettingsManager.get_last_dir( - self.mainwindow.servicemanagerSettingsSection), + UiStrings().SaveService, path, translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)'))) if not fileName: return False