Number of changes

- Allow time (24/12) hour for sage view
- Add pictorial display of the lay out in theme manage
- Fix bug where remote edit removes an overridden theme.

bzr-revno: 1770
This commit is contained in:
Tim Bentley 2011-10-05 19:20:54 +01:00
commit 161300fe73
12 changed files with 302 additions and 14 deletions

View File

@ -305,21 +305,37 @@ class Renderer(object):
The theme to build a text block for. The theme to build a text block for.
""" """
log.debug(u'_build_text_rectangle') log.debug(u'_build_text_rectangle')
main_rect = None main_rect = self.get_main_rectangle(theme)
footer_rect = None footer_rect = self.get_main_rectangle(theme)
self._set_text_rectangle(main_rect, footer_rect)
def get_main_rectangle(self, theme):
"""
Calculates the placement and size of the main rectangle.
``theme``
The theme information
"""
if not theme.font_main_override: if not theme.font_main_override:
main_rect = QtCore.QRect(10, 0, self.width - 20, self.footer_start) return QtCore.QRect(10, 0, self.width - 20, self.footer_start)
else: else:
main_rect = QtCore.QRect(theme.font_main_x, theme.font_main_y, return QtCore.QRect(theme.font_main_x, theme.font_main_y,
theme.font_main_width - 1, theme.font_main_height - 1) theme.font_main_width - 1, theme.font_main_height - 1)
def get_footer_rectangle(self, theme):
"""
Calculates the placement and size of the footer rectangle.
``theme``
The theme information
"""
if not theme.font_footer_override: if not theme.font_footer_override:
footer_rect = QtCore.QRect(10, self.footer_start, self.width - 20, return QtCore.QRect(10, self.footer_start, self.width - 20,
self.height - self.footer_start) self.height - self.footer_start)
else: else:
footer_rect = QtCore.QRect(theme.font_footer_x, return QtCore.QRect(theme.font_footer_x,
theme.font_footer_y, theme.font_footer_width - 1, theme.font_footer_y, theme.font_footer_width - 1,
theme.font_footer_height - 1) theme.font_footer_height - 1)
self._set_text_rectangle(main_rect, footer_rect)
def _set_text_rectangle(self, rect_main, rect_footer): def _set_text_rectangle(self, rect_main, rect_footer):
""" """

View File

@ -364,6 +364,11 @@ class ServiceItem(object):
""" """
self._uuid = other._uuid self._uuid = other._uuid
self.notes = other.notes self.notes = other.notes
# Copy theme over if present.
if other.theme is not None:
self.theme = other.theme
self._new_item()
self.render()
if self.is_capable(ItemCapabilities.HasBackgroundAudio): if self.is_capable(ItemCapabilities.HasBackgroundAudio):
log.debug(self.background_audio) log.debug(self.background_audio)

View File

@ -54,6 +54,7 @@ class HideMode(object):
from firsttimeform import FirstTimeForm from firsttimeform import FirstTimeForm
from firsttimelanguageform import FirstTimeLanguageForm from firsttimelanguageform import FirstTimeLanguageForm
from themelayoutform import ThemeLayoutForm
from themeform import ThemeForm from themeform import ThemeForm
from filerenameform import FileRenameForm from filerenameform import FileRenameForm
from starttimeform import StartTimeForm from starttimeform import StartTimeForm

View File

@ -1160,7 +1160,6 @@ class ServiceManager(QtGui.QWidget):
# if not passed set to config value # if not passed set to config value
if expand is None: if expand is None:
expand = self.expandTabs expand = self.expandTabs
item.render()
item.from_service = True item.from_service = True
if replace: if replace:
sitem, child = self.findServiceItem() sitem, child = self.findServiceItem()
@ -1169,6 +1168,7 @@ class ServiceManager(QtGui.QWidget):
self.repaintServiceList(sitem, child) self.repaintServiceList(sitem, child)
self.mainwindow.liveController.replaceServiceManagerItem(item) self.mainwindow.liveController.replaceServiceManagerItem(item)
else: else:
item.render()
# nothing selected for dnd # nothing selected for dnd
if self.dropPosition == 0: if self.dropPosition == 0:
if isinstance(item, list): if isinstance(item, list):

View File

@ -33,6 +33,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import Receiver, translate from openlp.core.lib import Receiver, translate
from openlp.core.lib.theme import BackgroundType, BackgroundGradientType from openlp.core.lib.theme import BackgroundType, BackgroundGradientType
from openlp.core.lib.ui import UiStrings, critical_error_message_box from openlp.core.lib.ui import UiStrings, critical_error_message_box
from openlp.core.ui import ThemeLayoutForm
from openlp.core.utils import get_images_filter from openlp.core.utils import get_images_filter
from themewizard import Ui_ThemeWizard from themewizard import Ui_ThemeWizard
@ -58,6 +59,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
self.registerFields() self.registerFields()
self.updateThemeAllowed = True self.updateThemeAllowed = True
self.temp_background_filename = u'' self.temp_background_filename = u''
self.themeLayoutForm = ThemeLayoutForm(self)
QtCore.QObject.connect(self.backgroundComboBox, QtCore.QObject.connect(self.backgroundComboBox,
QtCore.SIGNAL(u'currentIndexChanged(int)'), QtCore.SIGNAL(u'currentIndexChanged(int)'),
self.onBackgroundComboBoxCurrentIndexChanged) self.onBackgroundComboBoxCurrentIndexChanged)
@ -88,6 +90,9 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
self.onShadowCheckCheckBoxStateChanged) self.onShadowCheckCheckBoxStateChanged)
QtCore.QObject.connect(self.footerColorButton, QtCore.QObject.connect(self.footerColorButton,
QtCore.SIGNAL(u'clicked()'), self.onFooterColorButtonClicked) QtCore.SIGNAL(u'clicked()'), self.onFooterColorButtonClicked)
QtCore.QObject.connect(self,
QtCore.SIGNAL(u'customButtonClicked(int)'),
self.onCustom1ButtonClicked)
QtCore.QObject.connect(self.mainPositionCheckBox, QtCore.QObject.connect(self.mainPositionCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), QtCore.SIGNAL(u'stateChanged(int)'),
self.onMainPositionCheckBoxStateChanged) self.onMainPositionCheckBoxStateChanged)
@ -229,6 +234,10 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
""" """
Detects Page changes and updates as approprate. Detects Page changes and updates as approprate.
""" """
if self.page(pageId) == self.areaPositionPage:
self.setOption(QtGui.QWizard.HaveCustomButton1, True)
else:
self.setOption(QtGui.QWizard.HaveCustomButton1, False)
if self.page(pageId) == self.previewPage: if self.page(pageId) == self.previewPage:
self.updateTheme() self.updateTheme()
frame = self.thememanager.generateImage(self.theme) frame = self.thememanager.generateImage(self.theme)
@ -236,6 +245,25 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
self.displayAspectRatio = float(frame.width()) / frame.height() self.displayAspectRatio = float(frame.width()) / frame.height()
self.resizeEvent() self.resizeEvent()
def onCustom1ButtonClicked(self, number):
"""
Generate layout preview and display the form.
"""
self.updateTheme()
width = self.thememanager.mainwindow.renderer.width
height = self.thememanager.mainwindow.renderer.height
pixmap = QtGui.QPixmap(width, height)
pixmap.fill(QtCore.Qt.white)
paint = QtGui.QPainter(pixmap)
paint.setPen(QtGui.QPen(QtCore.Qt.blue, 2))
paint.drawRect(self.thememanager.mainwindow.renderer.
get_main_rectangle(self.theme))
paint.setPen(QtGui.QPen(QtCore.Qt.red, 2))
paint.drawRect(self.thememanager.mainwindow.renderer.
get_footer_rectangle(self.theme))
paint.end()
self.themeLayoutForm.exec_(pixmap)
def onOutlineCheckCheckBoxStateChanged(self, state): def onOutlineCheckCheckBoxStateChanged(self, state):
""" """
Change state as Outline check box changed Change state as Outline check box changed

View File

@ -0,0 +1,75 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund #
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate
from openlp.core.lib.ui import create_accept_reject_button_box
class Ui_ThemeLayoutDialog(object):
def setupUi(self, themeLayoutDialog):
themeLayoutDialog.setObjectName(u'themeLayoutDialogDialog')
#themeLayoutDialog.resize(300, 200)
self.previewLayout = QtGui.QVBoxLayout(themeLayoutDialog)
self.previewLayout.setObjectName(u'PreviewLayout')
self.previewArea = QtGui.QWidget(themeLayoutDialog)
self.previewArea.setObjectName(u'PreviewArea')
self.previewAreaLayout = QtGui.QGridLayout(self.previewArea)
self.previewAreaLayout.setMargin(0)
self.previewAreaLayout.setColumnStretch(0, 1)
self.previewAreaLayout.setRowStretch(0, 1)
self.previewAreaLayout.setObjectName(u'PreviewAreaLayout')
self.themeDisplayLabel = QtGui.QLabel(self.previewArea)
self.themeDisplayLabel.setFrameShape(QtGui.QFrame.Box)
self.themeDisplayLabel.setScaledContents(True)
self.themeDisplayLabel.setObjectName(u'ThemeDisplayLabel')
self.previewAreaLayout.addWidget(self.themeDisplayLabel)
self.previewLayout.addWidget(self.previewArea)
self.mainColourLabel = QtGui.QLabel(self.previewArea)
self.mainColourLabel.setObjectName(u'MainColourLabel')
self.previewLayout.addWidget(self.mainColourLabel)
self.footerColourLabel = QtGui.QLabel(self.previewArea)
self.footerColourLabel.setObjectName(u'FooterColourLabel')
self.previewLayout.addWidget(self.footerColourLabel)
self.buttonBox = QtGui.QDialogButtonBox(themeLayoutDialog)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Ok)
self.buttonBox.setObjectName(u'ButtonBox')
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'),
themeLayoutDialog.accept)
self.previewLayout.addWidget(self.buttonBox)
self.retranslateUi(themeLayoutDialog)
QtCore.QMetaObject.connectSlotsByName(themeLayoutDialog)
def retranslateUi(self, themeLayoutDialog):
themeLayoutDialog.setWindowTitle(
translate('OpenLP.StartTimeForm', 'Theme Layout'))
self.mainColourLabel.setText(translate('OpenLP.StartTimeForm',
'The blue box shows the main area.'))
self.footerColourLabel.setText(translate('OpenLP.StartTimeForm',
'The red box shows the footer.'))

View File

@ -0,0 +1,55 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund #
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
from PyQt4 import QtGui, QtCore
from themelayoutdialog import Ui_ThemeLayoutDialog
from openlp.core.lib import translate
from openlp.core.lib.ui import UiStrings, critical_error_message_box
class ThemeLayoutForm(QtGui.QDialog, Ui_ThemeLayoutDialog):
"""
The exception dialog
"""
def __init__(self, parent):
QtGui.QDialog.__init__(self, parent)
self.setupUi(self)
def exec_(self, image):
"""
Run the Dialog with correct heading.
"""
pixmap = image.scaledToHeight(400, QtCore.Qt.SmoothTransformation)
self.themeDisplayLabel.setPixmap(image)
displayAspectRatio = float(image.width()) / image.height()
self.themeDisplayLabel.setFixedSize(400, 400 / displayAspectRatio )
return QtGui.QDialog.exec_(self)
def accept(self):
return QtGui.QDialog.accept(self)

View File

@ -38,7 +38,8 @@ class Ui_ThemeWizard(object):
themeWizard.setModal(True) themeWizard.setModal(True)
themeWizard.setWizardStyle(QtGui.QWizard.ModernStyle) themeWizard.setWizardStyle(QtGui.QWizard.ModernStyle)
themeWizard.setOptions(QtGui.QWizard.IndependentPages | themeWizard.setOptions(QtGui.QWizard.IndependentPages |
QtGui.QWizard.NoBackButtonOnStartPage) QtGui.QWizard.NoBackButtonOnStartPage |
QtGui.QWizard.HaveCustomButton1)
self.spacer = QtGui.QSpacerItem(10, 0, self.spacer = QtGui.QSpacerItem(10, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum) QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum)
# Welcome Page # Welcome Page
@ -535,6 +536,9 @@ class Ui_ThemeWizard(object):
translate('OpenLP.ThemeWizard', 'px')) translate('OpenLP.ThemeWizard', 'px'))
self.footerPositionCheckBox.setText( self.footerPositionCheckBox.setText(
translate('OpenLP.ThemeWizard', 'Use default location')) translate('OpenLP.ThemeWizard', 'Use default location'))
themeWizard.setOption(QtGui.QWizard.HaveCustomButton1, False)
themeWizard.setButtonText(QtGui.QWizard.CustomButton1,
translate('OpenLP.ThemeWizard', 'Layout Preview'))
self.previewPage.setTitle( self.previewPage.setTitle(
translate('OpenLP.ThemeWizard', 'Save and Preview')) translate('OpenLP.ThemeWizard', 'Save and Preview'))
self.previewPage.setSubTitle( self.previewPage.setSubTitle(

View File

@ -121,11 +121,11 @@ window.OpenLP = {
$("#nextslide").html(text); $("#nextslide").html(text);
} }
}, },
updateClock: function() { updateClock: function(data) {
var div = $("#clock"); var div = $("#clock");
var t = new Date(); var t = new Date();
var h = t.getHours(); var h = t.getHours();
if (h > 12) if (data.results.twelve && h > 12)
h = h - 12; h = h - 12;
var m = t.getMinutes(); var m = t.getMinutes();
if (m < 10) if (m < 10)
@ -136,7 +136,7 @@ window.OpenLP = {
$.getJSON( $.getJSON(
"/api/poll", "/api/poll",
function (data, status) { function (data, status) {
OpenLP.updateClock(); OpenLP.updateClock(data);
if (OpenLP.currentItem != data.results.item) { if (OpenLP.currentItem != data.results.item) {
OpenLP.currentItem = data.results.item; OpenLP.currentItem = data.results.item;
OpenLP.loadSlides(); OpenLP.loadSlides();

View File

@ -315,7 +315,7 @@ class HttpConnection(object):
""" """
log.debug(u'ready to read socket') log.debug(u'ready to read socket')
if self.socket.canReadLine(): if self.socket.canReadLine():
data = unicode(self.socket.readLine()) data = unicode(self.socket.readLine()).encode(u'utf-8')
log.debug(u'received: ' + data) log.debug(u'received: ' + data)
words = data.split(u' ') words = data.split(u' ')
response = None response = None
@ -397,7 +397,9 @@ class HttpConnection(object):
result = { result = {
u'slide': self.parent.current_slide or 0, u'slide': self.parent.current_slide or 0,
u'item': self.parent.current_item._uuid \ u'item': self.parent.current_item._uuid \
if self.parent.current_item else u'' if self.parent.current_item else u'',
u'twelve':QtCore.QSettings().value(
u'remotes/twelve hour', QtCore.QVariant(True)).toBool()
} }
return HttpResponse(json.dumps({u'results': result}), return HttpResponse(json.dumps({u'results': result}),
{u'Content-Type': u'application/json'}) {u'Content-Type': u'application/json'})

View File

@ -57,6 +57,9 @@ class RemoteTab(SettingsTab):
QtCore.QObject.connect(self.addressEdit, QtCore.QObject.connect(self.addressEdit,
QtCore.SIGNAL(u'textChanged(const QString&)'), self.setUrls) QtCore.SIGNAL(u'textChanged(const QString&)'), self.setUrls)
self.serverSettingsLayout.addRow(self.addressLabel, self.addressEdit) self.serverSettingsLayout.addRow(self.addressLabel, self.addressEdit)
self.twelveHourCheckBox = QtGui.QCheckBox(self.serverSettingsGroupBox)
self.twelveHourCheckBox.setObjectName(u'twelveHourCheckBox')
self.serverSettingsLayout.addRow(self.twelveHourCheckBox)
self.portLabel = QtGui.QLabel(self.serverSettingsGroupBox) self.portLabel = QtGui.QLabel(self.serverSettingsGroupBox)
self.portLabel.setObjectName(u'portLabel') self.portLabel.setObjectName(u'portLabel')
self.portSpinBox = QtGui.QSpinBox(self.serverSettingsGroupBox) self.portSpinBox = QtGui.QSpinBox(self.serverSettingsGroupBox)
@ -80,6 +83,9 @@ class RemoteTab(SettingsTab):
self.leftLayout.addWidget(self.serverSettingsGroupBox) self.leftLayout.addWidget(self.serverSettingsGroupBox)
self.leftLayout.addStretch() self.leftLayout.addStretch()
self.rightLayout.addStretch() self.rightLayout.addStretch()
QtCore.QObject.connect(self.twelveHourCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'),
self.onTwelveHourCheckBoxChanged)
def retranslateUi(self): def retranslateUi(self):
self.serverSettingsGroupBox.setTitle( self.serverSettingsGroupBox.setTitle(
@ -92,6 +98,9 @@ class RemoteTab(SettingsTab):
'Remote URL:')) 'Remote URL:'))
self.stageUrlLabel.setText(translate('RemotePlugin.RemoteTab', self.stageUrlLabel.setText(translate('RemotePlugin.RemoteTab',
'Stage view URL:')) 'Stage view URL:'))
self.twelveHourCheckBox.setText(
translate('RemotePlugin.RemoteTab',
'Display stage time in 12h format'))
def setUrls(self): def setUrls(self):
ipAddress = u'localhost' ipAddress = u'localhost'
@ -123,6 +132,10 @@ class RemoteTab(SettingsTab):
self.addressEdit.setText( self.addressEdit.setText(
QtCore.QSettings().value(self.settingsSection + u'/ip address', QtCore.QSettings().value(self.settingsSection + u'/ip address',
QtCore.QVariant(ZERO_URL)).toString()) QtCore.QVariant(ZERO_URL)).toString())
self.twelveHour = QtCore.QSettings().value(
self.settingsSection + u'/twelve hour',
QtCore.QVariant(True)).toBool()
self.twelveHourCheckBox.setChecked(self.twelveHour)
self.setUrls() self.setUrls()
def save(self): def save(self):
@ -130,3 +143,11 @@ class RemoteTab(SettingsTab):
QtCore.QVariant(self.portSpinBox.value())) QtCore.QVariant(self.portSpinBox.value()))
QtCore.QSettings().setValue(self.settingsSection + u'/ip address', QtCore.QSettings().setValue(self.settingsSection + u'/ip address',
QtCore.QVariant(self.addressEdit.text())) QtCore.QVariant(self.addressEdit.text()))
QtCore.QSettings().setValue(self.settingsSection + u'/twelve hour',
QtCore.QVariant(self.twelveHour))
def onTwelveHourCheckBoxChanged(self, check_state):
self.twelveHour = False
# we have a set value convert to True/False
if check_state == QtCore.Qt.Checked:
self.twelveHour = True

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ThemeLayout</class>
<widget class="QDialog" name="ThemeLayout">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Theme Layout</string>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>50</x>
<y>260</y>
<width>341</width>
<height>32</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QLabel" name="themeDisplayLabel">
<property name="geometry">
<rect>
<x>20</x>
<y>10</y>
<width>361</width>
<height>231</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ThemeLayout</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ThemeLayout</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>