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.
"""
log.debug(u'_build_text_rectangle')
main_rect = None
footer_rect = None
main_rect = self.get_main_rectangle(theme)
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:
main_rect = QtCore.QRect(10, 0, self.width - 20, self.footer_start)
return QtCore.QRect(10, 0, self.width - 20, self.footer_start)
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)
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:
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)
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_height - 1)
self._set_text_rectangle(main_rect, footer_rect)
def _set_text_rectangle(self, rect_main, rect_footer):
"""

View File

@ -364,6 +364,11 @@ class ServiceItem(object):
"""
self._uuid = other._uuid
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):
log.debug(self.background_audio)

View File

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

View File

@ -1160,7 +1160,6 @@ class ServiceManager(QtGui.QWidget):
# if not passed set to config value
if expand is None:
expand = self.expandTabs
item.render()
item.from_service = True
if replace:
sitem, child = self.findServiceItem()
@ -1169,6 +1168,7 @@ class ServiceManager(QtGui.QWidget):
self.repaintServiceList(sitem, child)
self.mainwindow.liveController.replaceServiceManagerItem(item)
else:
item.render()
# nothing selected for dnd
if self.dropPosition == 0:
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.theme import BackgroundType, BackgroundGradientType
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 themewizard import Ui_ThemeWizard
@ -58,6 +59,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
self.registerFields()
self.updateThemeAllowed = True
self.temp_background_filename = u''
self.themeLayoutForm = ThemeLayoutForm(self)
QtCore.QObject.connect(self.backgroundComboBox,
QtCore.SIGNAL(u'currentIndexChanged(int)'),
self.onBackgroundComboBoxCurrentIndexChanged)
@ -88,6 +90,9 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
self.onShadowCheckCheckBoxStateChanged)
QtCore.QObject.connect(self.footerColorButton,
QtCore.SIGNAL(u'clicked()'), self.onFooterColorButtonClicked)
QtCore.QObject.connect(self,
QtCore.SIGNAL(u'customButtonClicked(int)'),
self.onCustom1ButtonClicked)
QtCore.QObject.connect(self.mainPositionCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'),
self.onMainPositionCheckBoxStateChanged)
@ -229,6 +234,10 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
"""
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:
self.updateTheme()
frame = self.thememanager.generateImage(self.theme)
@ -236,6 +245,25 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
self.displayAspectRatio = float(frame.width()) / frame.height()
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):
"""
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.setWizardStyle(QtGui.QWizard.ModernStyle)
themeWizard.setOptions(QtGui.QWizard.IndependentPages |
QtGui.QWizard.NoBackButtonOnStartPage)
QtGui.QWizard.NoBackButtonOnStartPage |
QtGui.QWizard.HaveCustomButton1)
self.spacer = QtGui.QSpacerItem(10, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum)
# Welcome Page
@ -535,6 +536,9 @@ class Ui_ThemeWizard(object):
translate('OpenLP.ThemeWizard', 'px'))
self.footerPositionCheckBox.setText(
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(
translate('OpenLP.ThemeWizard', 'Save and Preview'))
self.previewPage.setSubTitle(

View File

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

View File

@ -315,7 +315,7 @@ class HttpConnection(object):
"""
log.debug(u'ready to read socket')
if self.socket.canReadLine():
data = unicode(self.socket.readLine())
data = unicode(self.socket.readLine()).encode(u'utf-8')
log.debug(u'received: ' + data)
words = data.split(u' ')
response = None
@ -397,7 +397,9 @@ class HttpConnection(object):
result = {
u'slide': self.parent.current_slide or 0,
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}),
{u'Content-Type': u'application/json'})

View File

@ -57,6 +57,9 @@ class RemoteTab(SettingsTab):
QtCore.QObject.connect(self.addressEdit,
QtCore.SIGNAL(u'textChanged(const QString&)'), self.setUrls)
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.setObjectName(u'portLabel')
self.portSpinBox = QtGui.QSpinBox(self.serverSettingsGroupBox)
@ -80,6 +83,9 @@ class RemoteTab(SettingsTab):
self.leftLayout.addWidget(self.serverSettingsGroupBox)
self.leftLayout.addStretch()
self.rightLayout.addStretch()
QtCore.QObject.connect(self.twelveHourCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'),
self.onTwelveHourCheckBoxChanged)
def retranslateUi(self):
self.serverSettingsGroupBox.setTitle(
@ -92,6 +98,9 @@ class RemoteTab(SettingsTab):
'Remote URL:'))
self.stageUrlLabel.setText(translate('RemotePlugin.RemoteTab',
'Stage view URL:'))
self.twelveHourCheckBox.setText(
translate('RemotePlugin.RemoteTab',
'Display stage time in 12h format'))
def setUrls(self):
ipAddress = u'localhost'
@ -123,6 +132,10 @@ class RemoteTab(SettingsTab):
self.addressEdit.setText(
QtCore.QSettings().value(self.settingsSection + u'/ip address',
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()
def save(self):
@ -130,3 +143,11 @@ class RemoteTab(SettingsTab):
QtCore.QVariant(self.portSpinBox.value()))
QtCore.QSettings().setValue(self.settingsSection + u'/ip address',
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>