This commit is contained in:
Raoul Snyman 2010-04-23 21:20:44 +02:00
commit e22e76e183
272 changed files with 4876 additions and 4832 deletions

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #

View File

@ -1,58 +0,0 @@
This content can be found at this URL:
http://netsuperbrain.com/Postmodern%20PostgreSQL%20Application%20Development.pdf
Page 11-15: QtDesigner
Page 18-20: SQLAlchemy
Page 21-23: PyQt - widget
Page 24 : main
Page 28 : py2exe and release
==============================
This is the destilled content.
==============================
----------------
** sqlalchemy **
----------------
from sqlalchemy import create_engine, MetaData, Table
from sqlalchemy.orm import sessionmaker, mapper
engine = create_engine( 'postgres://postgres@localhost/customers' )
metadata = MetaData( bind=engine, reflect=True)
Session = sessionmaker(bind=engine, autoflush=True,
transactional=True)
class Customer(object): pass
mapper( Customer, Table('customers', metadata ) )
session = Session()
customer = Customer( businessName=“Jamb Safety”,
website=“www.jamb.com” )
session.save( customer )
for customer in Session.query(Customer).filter(
Customer.businessName.like(“Jamb%”)):
print customer.businessName
session.commit()
------------------------
** release and py2exe **
------------------------
from distutils.core import setup
import py2exe
import glob
setup(
name="Customers",
author="Sankel Software",
author_email="david@sankelsoftware.com",
url="http://sankelsoftware.com",
license=“GPL",
version=“1.0.0",
windows=[ { "script":"main.py“,}],
options={"py2exe":{"includes":["sip”]}},
data_files=[
("forms",glob.glob("forms/*.ui")),
] )
release:
python setup.py py2exe --quiet --dist-dir=dist

View File

@ -7,8 +7,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -34,7 +34,6 @@ from PyQt4 import QtCore, QtGui
log = logging.getLogger()
import openlp
from openlp.core.lib import Receiver, str_to_bool
from openlp.core.resources import qInitResources
from openlp.core.ui import MainWindow, SplashScreen, ScreenList
@ -79,9 +78,7 @@ class OpenLP(QtGui.QApplication):
Run the OpenLP application.
"""
#Load and store current Application Version
filepath = AppLocation.get_directory(AppLocation.AppDir)
if not hasattr(sys, u'frozen'):
filepath = os.path.join(filepath, u'openlp')
filepath = AppLocation.get_directory(AppLocation.VersionDir)
filepath = os.path.join(filepath, u'.version')
fversion = None
try:
@ -93,16 +90,23 @@ class OpenLP(QtGui.QApplication):
app_version = {
u'full': full_version,
u'version': bits[0],
u'build': bits[1]
u'build': bits[1] if len(bits) > 1 else None
}
log.info(u'Openlp version %s build %s' % (
app_version[u'version'], app_version[u'build']))
if app_version[u'build']:
log.info(
u'Openlp version %s build %s',
app_version[u'version'],
app_version[u'build']
)
else:
log.info(u'Openlp version %s' % app_version[u'version'])
except:
app_version = {
u'full': u'1.9.0-bzr000',
u'version': u'1.9.0',
u'build': u'bzr000'
}
log.exception('Error in version file.')
app_version = {
u'full': u'1.9.0-bzr000',
u'version': u'1.9.0',
u'build': u'bzr000'
}
finally:
if fversion:
fversion.close()

View File

@ -1 +1 @@
1.9.0-bzr722
1.9.0

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -21,4 +21,4 @@
# 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 #
###############################################################################
###############################################################################

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -21,4 +21,4 @@
# 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 #
###############################################################################
###############################################################################

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -144,8 +144,9 @@ def resize_image(image, width, height):
The image to resize.
"""
preview = QtGui.QImage(image)
preview = preview.scaled(width, height, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
if not preview.isNull():
preview = preview.scaled(width, height, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
realw = preview.width()
realh = preview.height()
# and move it to the centre of the preview space
@ -171,7 +172,7 @@ from mediamanageritem import MediaManagerItem
from xmlrootclass import XmlRootClass
from serviceitem import ServiceItem
from serviceitem import ServiceItemType
from serviceitem import ServiceItem
from serviceitem import ItemCapabilities
from toolbar import OpenLPToolbar
from dockwidget import OpenLPDockWidget
from songxmlhandler import SongXMLBuilder, SongXMLParser

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -109,6 +109,15 @@ class EventReceiver(QtCore.QObject):
``presentation types``
Informs all components of the presentation types supported.
``blank_check``
Check to see if th eblank display message is required
``version_check``
Version has changed so pop up window.
``mainDisplay_active``
Version has changed so pop up window.
"""
def __init__(self):
"""

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -114,6 +114,8 @@ class MediaManagerItem(QtGui.QWidget):
self.Toolbar = None
self.remoteTriggered = None
self.ServiceItemIconName = None
self.singleServiceItem = True
self.addToServiceItem = False
self.PageLayout = QtGui.QVBoxLayout(self)
self.PageLayout.setSpacing(0)
self.PageLayout.setContentsMargins(4, 0, 4, 0)
@ -131,6 +133,7 @@ class MediaManagerItem(QtGui.QWidget):
It provides a default set and the plugin is able to override
the if required.
"""
self.hasImportIcon = False
self.hasNewIcon = True
self.hasEditIcon = True
self.hasFileIcon = False
@ -207,48 +210,54 @@ class MediaManagerItem(QtGui.QWidget):
def addMiddleHeaderBar(self):
# Create buttons for the toolbar
## Import Button ##
if self.hasImportIcon:
self.addToolbarButton(
u'Import %s' % self.PluginNameShort,
u'%s %s' % (self.trUtf8('Import a'), self.PluginNameVisible),
u':/general/general_import.png', self.onImportClick)
## File Button ##
if self.hasFileIcon:
self.addToolbarButton(
u'Load %s' % self.PluginNameShort,
u'%s %s' % (self.trUtf8('Load a new'), self.PluginNameVisible),
u':/%s_load.png' % self.IconPath, self.onFileClick)
u':/general/general_open.png', self.onFileClick)
## New Button ##
if self.hasNewIcon:
self.addToolbarButton(
u'New %s' % self.PluginNameShort,
u'%s %s' % (self.trUtf8('Add a new'), self.PluginNameVisible),
u':/%s_new.png' % self.IconPath, self.onNewClick)
u':/general/general_new.png', self.onNewClick)
## Edit Button ##
if self.hasEditIcon:
self.addToolbarButton(
u'Edit %s' % self.PluginNameShort,
u'%s %s' % (self.trUtf8('Edit the selected'),
self.PluginNameVisible),
u':/%s_edit.png' % self.IconPath, self.onEditClick)
u':/general/general_edit.png', self.onEditClick)
## Delete Button ##
if self.hasDeleteIcon:
self.addToolbarButton(
u'Delete %s' % self.PluginNameShort,
self.trUtf8('Delete the selected item'),
u':/%s_delete.png' % self.IconPath, self.onDeleteClick)
u':/general/general_delete.png', self.onDeleteClick)
## Separator Line ##
self.addToolbarSeparator()
## Preview ##
self.addToolbarButton(
u'Preview %s' % self.PluginNameShort,
self.trUtf8('Preview the selected item'),
u':/system/system_preview.png', self.onPreviewClick)
u':/general/general_preview.png', self.onPreviewClick)
## Live Button ##
self.addToolbarButton(
u'Go Live',
self.trUtf8('Send the selected item live'),
u':/system/system_live.png', self.onLiveClick)
u':/general/general_live.png', self.onLiveClick)
## Add to service Button ##
self.addToolbarButton(
u'Add %s to Service' % self.PluginNameShort,
self.trUtf8('Add the selected item(s) to the service'),
u':/system/system_add.png', self.onAddClick)
u':/general/general_add.png', self.onAddClick)
def addListViewToToolBar(self):
#Add the List widget
@ -268,23 +277,36 @@ class MediaManagerItem(QtGui.QWidget):
if self.hasEditIcon:
self.ListView.addAction(
contextMenuAction(
self.ListView, u':/%s_new.png' % self.IconPath,
self.ListView, u':/general/general_edit.png',
u'%s %s' % (self.trUtf8('&Edit'), self.PluginNameVisible),
self.onEditClick))
self.ListView.addAction(contextMenuSeparator(self.ListView))
if self.hasDeleteIcon:
self.ListView.addAction(
contextMenuAction(
self.ListView, u':/general/general_delete.png',
u'%s %s' % (self.trUtf8('&Delete'), self.PluginNameVisible),
self.onDeleteClick))
self.ListView.addAction(contextMenuSeparator(self.ListView))
self.ListView.addAction(
contextMenuAction(
self.ListView, u':/system/system_preview.png',
self.ListView, u':/general/general_preview.png',
u'%s %s' % (self.trUtf8('&Preview'), self.PluginNameVisible),
self.onPreviewClick))
self.ListView.addAction(
contextMenuAction(
self.ListView, u':/system/system_live.png',
self.ListView, u':/general/general_live.png',
self.trUtf8('&Show Live'), self.onLiveClick))
self.ListView.addAction(
contextMenuAction(
self.ListView, u':/system/system_add.png',
self.ListView, u':/general/general_add.png',
self.trUtf8('&Add to Service'), self.onAddClick))
if self.addToServiceItem:
self.ListView.addAction(
contextMenuAction(
self.ListView, u':/general/general_add.png',
self.trUtf8('&Add to selected Service Item'),
self.onAddEditClick))
QtCore.QObject.connect(
self.ListView, QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
self.onPreviewClick)
@ -313,7 +335,7 @@ class MediaManagerItem(QtGui.QWidget):
files = QtGui.QFileDialog.getOpenFileNames(
self, self.OnNewPrompt,
self.parent.config.get_last_dir(), self.OnNewFileMasks)
log.info(u'New files(s)%s', unicode(files))
log.info(u'New files(s) %s', unicode(files))
if files:
self.loadList(files)
dir, filename = os.path.split(unicode(files[0]))
@ -330,6 +352,24 @@ class MediaManagerItem(QtGui.QWidget):
count += 1
return filelist
def validate(self, file, thumb):
"""
Validates to see if the file still exists or
thumbnail is up to date
"""
filedate = os.stat(file).st_mtime
thumbdate = os.stat(thumb).st_mtime
#if file updated rebuild icon
if filedate > thumbdate:
self.IconFromFile(file, thumb)
def IconFromFile(self, file, thumb):
icon = build_icon(unicode(file))
pixmap = icon.pixmap(QtCore.QSize(88,50))
ext = os.path.splitext(thumb)[1].lower()
pixmap.save(thumb, ext[1:])
return icon
def loadList(self, list):
raise NotImplementedError(u'MediaManagerItem.loadList needs to be '
u'defined by the plugin')
@ -346,47 +386,79 @@ class MediaManagerItem(QtGui.QWidget):
raise NotImplementedError(u'MediaManagerItem.onDeleteClick needs to '
u'be defined by the plugin')
def generateSlideData(self, item):
def generateSlideData(self, service_item, item):
raise NotImplementedError(u'MediaManagerItem.generateSlideData needs '
u'to be defined by the plugin')
def onPreviewClick(self):
if not self.ListView.selectedIndexes() and not self.remoteTriggered:
QtGui.QMessageBox.information(self,
self.trUtf8('No items selected...'),
self.trUtf8('You must select one or more items'))
self.trUtf8('No Items Selected'),
self.trUtf8('You must select one or more items.'))
else:
log.debug(self.PluginNameShort + u' Preview requested')
service_item = self.buildServiceItem()
if service_item:
service_item.fromPlugin = True
service_item.from_plugin = True
self.parent.preview_controller.addServiceItem(service_item)
def onLiveClick(self):
if not self.ListView.selectedIndexes():
QtGui.QMessageBox.information(self,
self.trUtf8('No items selected...'),
self.trUtf8('You must select one or more items'))
self.trUtf8('No Items Selected'),
self.trUtf8('You must select one or more items.'))
else:
log.debug(self.PluginNameShort + u' Live requested')
service_item = self.buildServiceItem()
if service_item:
service_item.fromPlugin = True
service_item.from_plugin = True
self.parent.live_controller.addServiceItem(service_item)
def onAddClick(self):
if not self.ListView.selectedIndexes() and not self.remoteTriggered:
QtGui.QMessageBox.information(self,
self.trUtf8('No items selected...'),
self.trUtf8('No Items Selected'),
self.trUtf8('You must select one or more items.'))
else:
#Is it posssible to process multiple list items to generate multiple
#service items?
if self.singleServiceItem:
log.debug(self.PluginNameShort + u' Add requested')
service_item = self.buildServiceItem()
if service_item:
service_item.from_plugin = False
self.parent.service_manager.addServiceItem(service_item)
else:
items = self.ListView.selectedIndexes()
for item in items:
service_item = self.buildServiceItem(item)
if service_item:
service_item.from_plugin = False
self.parent.service_manager.addServiceItem(service_item)
def onAddEditClick(self):
if not self.ListView.selectedIndexes() and not self.remoteTriggered:
QtGui.QMessageBox.information(self,
self.trUtf8('No items selected'),
self.trUtf8('You must select one or more items'))
else:
log.debug(self.PluginNameShort + u' Add requested')
service_item = self.buildServiceItem()
if service_item:
service_item.fromPlugin = False
service_item = self.parent.service_manager.getServiceItem()
if not service_item:
QtGui.QMessageBox.information(self,
self.trUtf8('No Service Item Selected'),
self.trUtf8('You must select a existing service item to add to.'))
elif self.title.lower() == service_item.name.lower():
self.generateSlideData(service_item)
self.parent.service_manager.addServiceItem(service_item)
else:
#Turn off the remote edit update message indicator
self.parent.service_manager.remoteEditTriggered = False
QtGui.QMessageBox.information(self,
self.trUtf8('Invalid Service Item'),
self.trUtf8(unicode('You must select a %s service item.' % self.title)))
def buildServiceItem(self):
def buildServiceItem(self, item=None):
"""
Common method for generating a service item
"""
@ -396,7 +468,7 @@ class MediaManagerItem(QtGui.QWidget):
else:
service_item.addIcon(
u':/media/media_' + self.PluginNameShort.lower() + u'.png')
if self.generateSlideData(service_item):
if self.generateSlideData(service_item, item):
return service_item
else:
return None
return None

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -139,8 +139,9 @@ class PluginConfig(object):
list = []
if list_count > 0:
for counter in range(0, list_count):
item = unicode(self.get_config(u'%s %d' % (name, counter)))
list.append(item)
item = self.get_config(u'%s %d' % (name, counter))
if item:
list.append(item)
return list
def set_list(self, name, list):
@ -190,4 +191,4 @@ class PluginConfig(object):
name = u'last directory %d' % num
else:
name = u'last directory'
self.set_config(name, directory)
self.set_config(name, directory)

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #

View File

@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -43,7 +43,6 @@ class Renderer(object):
"""
self._rect = None
self._debug = False
self._right_margin = 64 # the amount of right indent
self._display_shadow_size_footer = 0
self._display_outline_size_footer = 0
self.theme_name = None
@ -149,7 +148,7 @@ class Renderer(object):
def pre_render_text(self, text):
metrics = QtGui.QFontMetrics(self.mainFont)
#work out line width
line_width = self._rect.width() - self._right_margin
line_width = self._rect.width()
#number of lines on a page - adjust for rounding up.
line_height = metrics.height()
if self._theme.display_shadow:
@ -224,6 +223,7 @@ class Renderer(object):
``rect_footer``
The footer text block.
"""
log.debug(u'set_text_rectangle %s , %s' %(rect_main, rect_footer) )
self._rect = rect_main
self._rect_footer = rect_footer
@ -447,8 +447,7 @@ class Renderer(object):
rightextent = x + w
# shift right from last line's rh edge
if self._theme.display_wrapStyle == 1 and linenum != 0:
rightextent = self._first_line_right_extent + \
self._right_margin
rightextent = self._first_line_right_extent
if rightextent > maxx:
rightextent = maxx
x = rightextent - w
@ -467,8 +466,7 @@ class Renderer(object):
tlcorner=(x + display_shadow_size, y + display_shadow_size),
draw=True, color = self._theme.display_shadow_color)
self._get_extent_and_render(line, footer, tlcorner=(x, y), draw=True,
outline_size=display_outline_size,
outline_color=self._theme.display_outline_color)
outline_size=display_outline_size)
y += h
if linenum == 0:
self._first_line_right_extent = rightextent
@ -506,7 +504,7 @@ class Renderer(object):
self.mainFont.setPixelSize(self._theme.font_main_proportion)
def _get_extent_and_render(self, line, footer, tlcorner=(0, 0), draw=False,
color=None, outline_size=None, outline_color=None):
color=None, outline_size=0):
"""
Find bounding box of text - as render_single_line. If draw is set,
actually draw the text to the current DC as well return width and
@ -545,21 +543,23 @@ class Renderer(object):
else:
pen = QtGui.QColor(color)
x, y = tlcorner
if outline_size:
if self._theme.display_outline and outline_size != 0 and not footer:
path = QtGui.QPainterPath()
path.addText(QtCore.QPointF(x, y + metrics.ascent()), font, line)
self.painter.setBrush(self.painter.pen().brush())
self.painter.setPen(QtGui.QPen(QtGui.QColor(outline_color), outline_size))
self.painter.setPen(QtGui.QPen(
QtGui.QColor(self._theme.display_outline_color), outline_size))
self.painter.drawPath(path)
self.painter.setPen(pen)
self.painter.drawText(x, y + metrics.ascent(), line)
if self._theme.display_slideTransition:
# Print 2nd image with 70% weight
if outline_size:
if self._theme.display_outline and outline_size != 0 and not footer:
path = QtGui.QPainterPath()
path.addText(QtCore.QPointF(x, y + metrics.ascent()), font, line)
self.painter2.setBrush(self.painter2.pen().brush())
self.painter2.setPen(QtGui.QPen(QtGui.QColor(outline_color), outline_size))
self.painter2.setPen(QtGui.QPen(
QtGui.QColor(self._theme.display_outline_color), outline_size))
self.painter2.drawPath(path)
self.painter2.setFont(font)
self.painter2.setPen(pen)

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -49,7 +49,7 @@ class RenderManager(object):
"""
log.info(u'RenderManager Loaded')
def __init__(self, theme_manager, screens, screen_number=0):
def __init__(self, theme_manager, screens):
"""
Initialise the render manager.
"""
@ -57,7 +57,6 @@ class RenderManager(object):
self.screens = screens
self.theme_manager = theme_manager
self.renderer = Renderer()
self.screens.set_current_display(screen_number)
self.calculate_default(self.screens.current[u'size'])
self.theme = u''
self.service_theme = u''
@ -65,12 +64,9 @@ class RenderManager(object):
self.override_background = None
self.themedata = None
def update_display(self, screen_number):
def update_display(self):
"""
Updates the render manager's information about the current screen.
``screen_number``
The updated index of the output/display screen.
"""
log.debug(u'Update Display')
self.calculate_default(self.screens.current[u'size'])
@ -146,13 +142,13 @@ class RenderManager(object):
footer_rect = None
if not theme.font_main_override:
main_rect = QtCore.QRect(10, 0,
self.width - 1, self.footer_start)
self.width - 20, self.footer_start)
else:
main_rect = QtCore.QRect(theme.font_main_x, theme.font_main_y,
theme.font_main_width - 1, theme.font_main_height - 1)
if not theme.font_footer_override:
footer_rect = QtCore.QRect(10, self.footer_start,
self.width - 1, self.height - self.footer_start)
self.width - 20, self.height - self.footer_start)
else:
footer_rect = QtCore.QRect(theme.font_footer_x,
theme.font_footer_y, theme.font_footer_width - 1,

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -42,6 +42,14 @@ class ServiceItemType(object):
Image = 2
Command = 3
class ItemCapabilities(object):
AllowsPreview = 1
AllowsEdit = 2
AllowsMaintain = 3
RequiresMedia = 4
AllowsLoop = 5
class ServiceItem(object):
"""
The service item is a base class for the plugins to use to interact with
@ -66,14 +74,19 @@ class ServiceItem(object):
self.iconic_representation = None
self.raw_footer = None
self.theme = None
self.service_item_path = None
self.service_item_type = None
self.edit_enabled = False
self._raw_frames = []
self._display_frames = []
self._uuid = unicode(uuid.uuid1())
self.autoPreviewAllowed = False
self.notes = u''
self.from_plugin = False
self.capabilities = []
def add_capability(self, capability):
self.capabilities.append(capability)
def is_capable(self, capability):
return capability in self.capabilities
def addIcon(self, icon):
"""
@ -156,9 +169,8 @@ class ServiceItem(object):
The actual image file name.
"""
self.service_item_type = ServiceItemType.Image
self.service_item_path = path
self._raw_frames.append(
{u'title': title, u'image': image})
{u'title': title, u'image': image, u'path': path})
def add_from_text(self, title, raw_slide, verseTag=None):
"""
@ -189,9 +201,8 @@ class ServiceItem(object):
The command of/for the slide.
"""
self.service_item_type = ServiceItemType.Command
self.service_item_path = path
self._raw_frames.append(
{u'title': file_name, u'image': image})
{u'title': file_name, u'image': image, u'path': path})
def get_service_repr(self):
"""
@ -208,7 +219,8 @@ class ServiceItem(object):
u'type':self.service_item_type,
u'audit':self.audit,
u'notes':self.notes,
u'preview':self.autoPreviewAllowed
u'from_plugin':self.from_plugin,
u'capabilities':self.capabilities
}
service_data = []
if self.service_item_type == ServiceItemType.Text:
@ -242,8 +254,9 @@ class ServiceItem(object):
self.addIcon(header[u'icon'])
self.raw_footer = header[u'footer']
self.audit = header[u'audit']
self.autoPreviewAllowed = header[u'preview']
self.notes = header[u'notes']
self.from_plugin = header[u'from_plugin']
self.capabilities = header[u'capabilities']
if self.service_item_type == ServiceItemType.Text:
for slide in serviceitem[u'serviceitem'][u'data']:
self._raw_frames.append(slide)
@ -279,11 +292,8 @@ class ServiceItem(object):
"""
return self._uuid != other._uuid
def is_song(self):
return self.name == u'Songs'
def is_media(self):
return self.name.lower() == u'media'
return ItemCapabilities.RequiresMedia in self.capabilities
def is_command(self):
return self.service_item_type == ServiceItemType.Command
@ -320,6 +330,12 @@ class ServiceItem(object):
"""
return self._raw_frames[row][u'title']
def get_frame_path(self, row=0):
"""
Returns the title of the raw frame
"""
return self._raw_frames[row][u'path']
def request_audit(self):
if self.audit:
Receiver.send_message(u'songusage_live', self.audit)

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -54,6 +54,7 @@ class SettingsTab(QtGui.QWidget):
self.config = PluginConfig(title)
else:
self.config = PluginConfig(section)
self.preLoad()
self.load()
def setupUi(self):
@ -62,6 +63,12 @@ class SettingsTab(QtGui.QWidget):
"""
pass
def preLoad(self):
"""
Setup the tab's interface.
"""
pass
def retranslateUi(self):
"""
Setup the interface translation strings.
@ -90,4 +97,4 @@ class SettingsTab(QtGui.QWidget):
"""
Changes which need to be made after setup of application
"""
pass
pass

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -148,6 +148,8 @@ class SongXMLParser(object):
verse_list = []
for element in iter:
if element.tag == u'verse':
if element.text is None:
element.text = u''
verse_list.append([element.attrib,
unicode(element.text).decode('unicode-escape')])
return verse_list

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -53,7 +53,7 @@ blankthemexml=\
<weight>Normal</weight>
<italics>False</italics>
<indentation>0</indentation>
<location override="False" x="10" y="10" width="1024" height="730"/>
<location override="False" x="10" y="10" width="1004" height="730"/>
</font>
<font type="footer">
<name>Arial</name>
@ -62,7 +62,7 @@ blankthemexml=\
<weight>Normal</weight>
<italics>False</italics>
<indentation>0</indentation>
<location override="False" x="10" y="730" width="1024" height="38"/>
<location override="False" x="10" y="730" width="1004" height="38"/>
</font>
<display>
<shadow color="#000000" size="5">True</shadow>

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<Theme>
<Name>openlp.org Packaged Theme</Name>
<BackgroundType>0</BackgroundType>
<BackgroundParameter1>clWhite</BackgroundParameter1>
<BackgroundParameter2/>
<BackgroundParameter3/>
<FontName>Tahoma</FontName>
<FontColor>$00007F</FontColor>
<FontProportion>53</FontProportion>
<FontUnits>pixels</FontUnits>
<Shadow>0</Shadow>
<ShadowColor>$000000</ShadowColor>
<Outline>0</Outline>
<OutlineColor>$000000</OutlineColor>
<HorizontalAlign>0</HorizontalAlign>
<VerticalAlign>0</VerticalAlign>
<WrapStyle>1</WrapStyle>
</Theme>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 517 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

View File

@ -1,85 +0,0 @@
import logging
import os
import sys
from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(name)-30s %(levelname)-8s %(message)s',
datefmt='%m-%d %H:%M',
filename='plugins.log',
filemode='w')
console=logging.StreamHandler()
# set a format which is simpler for console use
formatter = logging.Formatter(u'%(name)24s: %(levelname)-8s %(message)s')
# tell the handler to use this format
console.setFormatter(formatter)
logging.getLogger(u'').addHandler(console)
log = logging.getLogger(u'')
logging.info(u'Logging started')
mypath = os.path.split(os.path.abspath(__file__))[0]
sys.path.insert(0,(os.path.join(mypath, '..' ,'..', '..')))
class TestMediaManager:
def setup_class(self):
self.app = QtGui.QApplication([])
logging.info (u'App is ' + unicode(self.app))
self.main_window = QtGui.QMainWindow()
self.main_window.resize(200, 600)
self.MediaManagerDock = QtGui.QDockWidget(self.main_window)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(
self.MediaManagerDock.sizePolicy().hasHeightForWidth())
self.MediaManagerDock.setSizePolicy(sizePolicy)
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(u':/system/system_mediamanager.png'),
QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.MediaManagerDock.setWindowIcon(icon)
self.MediaManagerDock.setFloating(False)
self.MediaManagerContents = QtGui.QWidget()
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(
self.MediaManagerContents.sizePolicy().hasHeightForWidth())
self.MediaManagerContents.setSizePolicy(sizePolicy)
self.MediaManagerLayout = QtGui.QHBoxLayout(self.MediaManagerContents)
self.MediaManagerLayout.setContentsMargins(0, 2, 0, 0)
self.MediaToolBox = QtGui.QToolBox(self.MediaManagerContents)
self.MediaManagerDock.setWidget(self.MediaManagerContents)
self.main_window.addDockWidget(QtCore.Qt.DockWidgetArea(1),
self.MediaManagerDock)
self.MediaManagerLayout.addWidget(self.MediaToolBox)
def test1(self):
log=logging.getLogger(u'test1')
log.info(u'Start')
i1=MediaManagerItem(self.MediaToolBox)
i2=MediaManagerItem(self.MediaToolBox)
log.info(u'i1'+unicode(i1))
log.info(u'i2'+unicode(i2))
i1.addToolbar()
i1.addToolbarButton(u'Test1', u'Test1', None)
i2.addToolbar()
i2.addToolbarButton(u'Test2', u'Test2', None)
self.MediaToolBox.setItemText(
self.MediaToolBox.indexOf(i1), self.trUtf8('Item1'))
self.MediaToolBox.setItemText(
self.MediaToolBox.indexOf(i2), self.trUtf8('Item2'))
log.info(u'Show window')
self.main_window.show()
log.info(u'End')
return 1
if __name__ == "__main__":
t=TestMediaManager()
t.setup_class()
t.test1()
log.info(u'exec')
sys.exit(t.app.exec_())

View File

@ -1,49 +0,0 @@
import logging
import os
import sys
from openlp.core.lib.pluginmanager import PluginManager
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
datefmt='%m-%d %H:%M',
filename='plugins.log',
filemode='w')
console=logging.StreamHandler()
# set a format which is simpler for console use
formatter = logging.Formatter(u'%(name)-12s: %(levelname)-8s %(message)s')
# tell the handler to use this format
console.setFormatter(formatter)
logging.getLogger(u'').addHandler(console)
log = logging.getLogger(u'')
logging.info(u'Logging started')
mypath = os.path.split(os.path.abspath(__file__))[0]
sys.path.insert(0,(os.path.join(mypath, '..' ,'..', '..')))
# test the plugin manager with some plugins in the test_plugins directory
class TestPluginManager:
def test_init(self):
self.p = PluginManager(u'./testplugins')
p = self.p
p.find_plugins(u'./testplugins', None, None)
assert(len(p.plugins) == 2)
# get list of the names of the plugins
names = [plugin.name for plugin in p.plugins]
# see which ones we've got
assert(u'testplugin1' in names)
assert(u'testplugin2' in names)
# and not got - it's too deep in the hierarchy!
assert(u'testplugin3' not in names)
# test that the weighting is done right
assert(p.plugins[0].name == "testplugin2")
assert(p.plugins[1].name == "testplugin1")
if __name__ == "__main__":
log.debug(u'Starting')
t = TestPluginManager()
t.test_init()
log.debug(u'List of plugins found:')
for plugin in t.p.plugins:
log.debug(u'Plugin %s, name=%s (version=%d)' %(unicode(plugin),
plugin.name, plugin.version))

View File

@ -1,234 +0,0 @@
"""
OpenLP - Open Source Lyrics Projection
Copyright (c) 2008 Raoul Snyman
Portions copyright (c) 2008 Martin Thompson, Tim Bentley
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
"""
import sys
import os
import os.path
from PyQt4 import QtGui, QtCore
from openlp.core.theme import Theme
from openlp.core.lib import Renderer
mypath = os.path.split(os.path.abspath(__file__))[0]
sys.path.insert(0, (os.path.join(mypath, '..', '..', '..')))
# from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66062
def whoami(depth=1):
return sys._getframe(depth).f_code.co_name
class TstFrame:
# {{{ init
def __init__(self, size):
"""Create the DemoPanel."""
self.width = size.width();
self.height = size.height();
# create something to be painted into
self._Buffer = QtGui.QPixmap(self.width, self.height)
def GetPixmap(self):
return self._Buffer
# }}}
class TestRender_base:
def __init__(self):
if not os.path.exists(u'test_results'):
os.mkdir(u'test_results')
self.app = None
def write_to_file(self, pixmap, name):
im=pixmap.toImage()
testpathname = os.path.join(u'test_results', name+'.bmp')
if os.path.exists(testpathname):
os.unlink(testpathname)
im.save(testpathname, 'bmp')
return im
# xxx quitting the app still leaves it hanging aroudn so we die
# when trying to start another one. Not quitting doesn't help
# though This means that the py.test runs both test modules in
# sequence and the second one tries to create another application
# which gives us errors :(
def setup_class(self):
print "class setup", self
try:
if self.app is None:
pass
except AttributeError: # didn't have one
print "No app"
self.app = None
print "Test app (should be None)"
if self.app is None:
print "App is None"
self.app = QtGui.QApplication([])
else:
print "class setup, app is", app
# self.app = QtGui.QApplication([])
def teardown_class(self):
print "class quit", self, self.app
self.app.quit()
def setup_method(self, method):
print "SSsetup", method
if not hasattr(self, 'app'):
self.app = None
try: # see if we already have an app for some reason.
# have to try and so something, cant just test against None
print "app", self.app, ";;;"
print self.app.quit()
print "quitted"
except RuntimeError: # not valid app, create one
print "Runtime error"
except AttributeError: # didn't have one
print "Attribute error"
# print "App", self.app
# self.app = QtGui.QApplication([])
print "Application created and sorted"
self.size = QtCore.QSize(800,600)
frame = TstFrame(size = self.size)
self.frame = frame
self.paintdest = frame.GetPixmap()
self.renderer = Renderer()
self.renderer.set_paint_dest(self.paintdest)
self.expected_answer = "Don't know yet"
self.answer = None
print "--------------- Setup Done -------------"
def teardown_method(self, method):
self.write_to_file(self.frame.GetPixmap(), 'test_render')
class TestRender(TestRender_base):
def __init__(self):
TestRender_base.__init__(self)
def setup_method(self, method):
TestRender_base.setup_method(self, method)
self.renderer.set_debug(1)
themefile = os.path.abspath(u'data_for_tests/render_theme.xml')
self.renderer.set_theme(Theme(themefile)) # set default theme
self.renderer._render_background()
self.renderer.set_text_rectangle(QtCore.QRect(
0,0, self.size.width()-1, self.size.height()-1))
self.msg = None
def test_easy(self):
answer = self.renderer._render_single_line(
u'Test line', tlcorner = (0,100))
assert(answer == (219,163))
def test_longer(self):
answer = self.renderer._render_single_line(
u'Test line with more words than fit on one line',
tlcorner = (10,10))
assert(answer == (753,136))
def test_even_longer(self):
answer = self.renderer._render_single_line(
u'Test line with more words than fit on either one or two lines',
tlcorner = (10,10))
assert(answer == (753,199))
def test_lines(self):
lines = []
lines.append(u'Line One')
lines.append(u'Line Two')
lines.append(u'Line Three and should be long enough to wrap')
lines.append(u'Line Four and should be long enough to wrap also')
answer = self.renderer._render_lines(lines)
assert(answer == QtCore.QRect(0,0,741,378))
def test_set_words_openlp(self):
words="""
Verse 1: Line 1
Line 2
Verse 2: Line 1
Line 2
Verse 3: Line 1
Line 2
Line 3"""
expected_answer = ["Verse 1: Line 1\nLine 2","Verse 2: Line 1\nLine 2","Verse 3: Line 1\nLine 2\nLine 3"]
answer = self.renderer.set_words_openlp(words)
assert(answer == expected_answer)
def test_render_screens(self):
words="""
Verse 1: Line 1
Line 2
Verse 2: Line 1
Line 2
Verse 3: Line 1
Line 2
Line 3"""
verses = self.renderer.set_words_openlp(words)
expected_answer = ["Verse 1: Line 1\nLine 2","Verse 2: Line 1\nLine 2","Verse 3: Line 1\nLine 2\nLine 3"]
assert(verses == expected_answer)
expected_answer = [QtCore.QRect(0,0,397,126), QtCore.QRect(0,0,397,126),
QtCore.QRect(0,0,397,189)]
for v in range(len(verses)):
answer=self.renderer.render_screen(v)
# print v, answer.x(), answer.y(), answer.width(), answer.height()
assert(answer == expected_answer[v])
def split_test(self, number, answer, expected_answers):
lines=[]
print "Split test", number, answer
for i in range(number):
extra=""
if i == 51: # make an extra long line on line 51 to test wrapping
extra = "Some more words to make it wrap around don't you know until it wraps so many times we don't know what to do"
lines.append(u'Line %d %s' % (i, extra))
result = self.renderer.split_set_of_lines(lines)
print "results---------------__", result
for i in range(len(result)):
self.setup_method(None)
answer = self.renderer._render_lines(result[i])
print answer
self.write_to_file(self.frame.GetPixmap(), "split_test_%03d"% i)
print number, i, answer.x(), answer.y(), answer.width(), \
answer.height()
e = expected_answers[i]
assert(answer == QtCore.QRect(e[0],e[1],e[2],e[3]))
def test_splits(self):
print "Test splits"
self.split_test(100, 11, [(0,0,180,567), (0,0,214,567), (0,0,214,567),
(0,0,214,567), (0,0,214,567), (0,0,214,378), (0,0,759,567),
(0,0,214,567), (0,0,214,567), (0,0,214,567), (0,0,214,567),
(0,0,214,567), (0,0,214,567)])
self.split_test(30, 4, [ (0,0,180,441), (0,0,214,441), (0,0,214,441),
(0,0,214,441)])
self.split_test(20, 3, [(0,0,180,378), (0,0,214,378), (0,0,214,378)])
self.split_test(12, 2, [(0,0,180,378), (0,0,214,378)])
self.split_test(4, 1, [(0,0,180,252)])
self.split_test(6, 1, [(0,0,180,378)])
self.split_test(8, 1, [(0,0,180,504)])
if __name__ == "__main__":
t = TestRender()
t.setup_class()
t.setup_method(None)
t.test_easy()
t.test_splits()
t.teardown_method(None)

View File

@ -1,312 +0,0 @@
"""
OpenLP - Open Source Lyrics Projection
Copyright (c) 2008 Raoul Snyman
Portions copyright (c) 2008 Martin Thompson, Tim Bentley
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
"""
import sys
import os
from PyQt4 import QtGui, QtCore
from openlp.core.theme import Theme
from test_render import TestRender_base, whoami
pypath = os.path.split(os.path.abspath(__file__))[0]
sys.path.insert(0, (os.path.join(mypath, '..', '..', '..')))
def compare_images(goldenim, testim, threshold=0.01):
# easy test first
if goldenim == testim:
return 1
# how close are they? Calculated the sum of absolute differences in
# each channel of each pixel and divide by the number of pixels in the image
# if this sum is < threshold, the images are deemed to be "close enough"
sad = 0;
for x in range(goldenim.width()):
for y in range(goldenim.height()):
p1=goldenim.pixel(x,y)
p2=testim.pixel(x,y)
sad += abs((p1&0xFF)-(p2&0xFF))
sad += abs((p1>>8&0xFF)-(p2>>8&0xFF))
sad += abs((p1>>16&0xFF)-(p2>>16&0xFF))
sad /= float(goldenim.width()*goldenim.height())
if (sad < threshold):
return 1
return 0
class TestRenderTheme(TestRender_base):
# {{{ Basics
def __init__(self):
TestRender_base.__init__(self)
def setup_method(self, method):
TestRender_base.setup_method(self, method)
print "Theme setup", method
# print "setup theme"
self.renderer.set_theme(Theme(u'blank_theme.xml')) # set "blank" theme
self.renderer.set_text_rectangle(QtCore.QRect(0,0, self.size.width(),
self.size.height()))
words = """How sweet the name of Jesus sounds
In a believer's ear!
It soothes his sorrows, heals his wounds,
And drives away his fear.
"""
verses = self.renderer.set_words_openlp(words)
# usually the same
self.expected_answer = QtCore.QRect(0, 0, 559, 342)
self.msg = None
self.bmpname = "Not set a bitmap yet"
print "------------- setup done --------------"
def teardown_method(self, method):
print "============ teardown =============", method, self.bmpname
if self.bmpname is not None:
assert (self.compare_DC_to_file(self.bmpname))
if self.expected_answer is not None: # result=None => Nothing to check
assert self.expected_answer == self.answer
print "============ teardown done ========="
def compare_DC_to_file(self, name):
"""writes DC out to a bitmap file and then compares it with a golden
one returns True if OK, False if not (so you can assert on it)
"""
print "--- compare DC to file --- ", name
p = self.frame.GetPixmap()
im = self.write_to_file(p, name)
print "Compare"
goldenfilename=os.path.join(u'golden_bitmaps",name+".bmp')
if os.path.exists(goldenfilename):
goldenim = QtGui.QImage(goldenfilename)
else:
print "File", goldenfilename, "not found"
return False
if (compare_images(goldenim, im)):
print name, "Images match"
return True
else:
print name, goldenfilename, "Images don't match"
return False
def test_theme_basic(self):
self.answer = self.renderer.render_screen(0)
self.bmpname = whoami()
print self.renderer._theme.FontProportion
print self.answer, self.expected_answer, \
self.answer == self.expected_answer
# self.msg=self.bmpname
# }}}
# {{{ Gradients
def test_gradient_h(self):
# normally we wouldn't hack with these directly!
self.renderer._theme.BackgroundType = 1
self.renderer._theme.BackgroundParameter1 = QtGui.QColor(255,0,0)
self.renderer._theme.BackgroundParameter2 = QtGui.QColor(255,255,0)
self.renderer._theme.BackgroundParameter3 = 1
self.answer = self.renderer.render_screen(0)
self.bmpname = whoami()
def test_gradient_v(self):
# normally we wouldn't hack with these directly!
self.renderer._theme.BackgroundType = 1
self.renderer._theme.BackgroundParameter1 = QtGui.QColor(255,0,0)
self.renderer._theme.BackgroundParameter2 = QtGui.QColor(255,255,0)
self.renderer._theme.BackgroundParameter3 = 0
self.answer = self.renderer.render_screen(0)
self.bmpname = whoami()
# }}}
# {{{ backgrounds
def test_bg_stretch_y(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 2
t.BackgroundParameter1 = os.path.join(u'data_for_tests',
'snowsmall.jpg')
t.BackgroundParameter2 = QtGui.QColor(0,0,64)
t.BackgroundParameter3 = 0
t.Name = "stretch y"
self.renderer.set_theme(t)
print "render"
self.answer = self.renderer.render_screen(0)
print "whoami"
self.bmpname = whoami()
print "fone"
def test_bg_shrink_y(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 2
t.BackgroundParameter1 = os.path.join(u'data_for_tests', 'snowbig.jpg')
t.BackgroundParameter2 = QtGui.QColor(0,0,64)
t.BackgroundParameter3 = 0
t.Name = "shrink y"
self.renderer.set_theme(t)
self.answer = self.renderer.render_screen(0)
self.bmpname = whoami()
def test_bg_stretch_x(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 2
t.BackgroundParameter1 = os.path.join(u'data_for_tests',
'treessmall.jpg')
t.BackgroundParameter2 = QtGui.QColor(0,0,64)
t.BackgroundParameter3 = 0
t.VerticalAlign = 2
t.Name = "stretch x"
self.renderer.set_theme(t)
self.answer = self.renderer.render_screen(0)
self.expected_answer = QtCore.QRect(0, 129, 559, 342)
self.bmpname = whoami()
def test_bg_shrink_x(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 2
t.BackgroundParameter1 = os.path.join(u'data_for_tests',
'treesbig.jpg')
t.BackgroundParameter2 = QtGui.QColor(0,0,64)
t.BackgroundParameter3 = 0
t.VerticalAlign = 2
t.Name = "shrink x"
self.renderer.set_theme(t)
self.expected_answer = QtCore.QRect(0, 129, 559, 342)
self.answer = self.renderer.render_screen(0)
self.bmpname = whoami()
# }}}
# {{{ Vertical alignment
def test_theme_vertical_align_top(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,64)
t.VerticalAlign = 0
t.Name = "valign top"
self.renderer.set_theme(t)
self.answer = self.renderer.render_screen(0)
self.bmpname = whoami()
def test_theme_vertical_align_bot(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,64)
t.VerticalAlign = 1
t.Name = "valign bot"
self.renderer.set_theme(t)
self.answer = self.renderer.render_screen(0)
self.expected_answer = QtCore.QRect(0, 257, 559, 342)
self.bmpname = whoami()
def test_theme_vertical_align_cen(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,64)
t.VerticalAlign = 2
t.Name = "valign cen"
self.renderer.set_theme(t)
self.answer = self.renderer.render_screen(0)
self.expected_answer = QtCore.QRect(0, 129, 559, 342)
self.bmpname = whoami()
# }}}
# {{{ Horzontal alignment
def test_theme_horizontal_align_left(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,64)
t.VerticalAlign = 0
t.HorizontalAlign = 0
t.Name = "halign left"
self.renderer.set_theme(t)
self.answer = self.renderer.render_screen(0)
self.bmpname = whoami()
def test_theme_horizontal_align_right(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,64)
t.VerticalAlign = 0
t.HorizontalAlign = 1
t.Name = "halign right"
self.renderer.set_theme(t)
self.expected_answer = QtCore.QRect(0, 0, 800, 342)
self.answer = self.renderer.render_screen(0)
self.bmpname = whoami()
def test_theme_horizontal_align_centre(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,64)
t.VerticalAlign = 0
t.HorizontalAlign = 2
t.Name = "halign centre"
self.renderer.set_theme(t)
self.answer = self.renderer.render_screen(0)
self.expected_answer = QtCore.QRect(0, 0, 679, 342)
self.bmpname = whoami()
def test_theme_horizontal_align_left_lyric(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,64)
t.VerticalAlign = 0
t.HorizontalAlign = 0
t.WrapStyle = 1
t.Name = "halign left lyric"
self.renderer.set_theme(t)
self.answer = self.renderer.render_screen(0)
self.expected_answer = QtCore.QRect(0, 0, 778, 342)
self.bmpname = whoami()
# }}}
# {{{ Shadows and outlines
def test_theme_shadow_outline(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,0);
t.Name="shadow/outline"
t.Shadow = 1
t.Outline = 1
t.ShadowColor = QtGui.QColor(64,128,0)
t.OutlineColor = QtGui.QColor(128,0,0)
self.renderer.set_debug(1)
self.renderer.set_theme(t)
self.answer = self.renderer.render_screen(0)
hoffset = self.renderer._shadow_offset+2*(self.renderer._outline_offset)
voffset = hoffset * (len(self.renderer.words[0])+1)
self.expected_answer = QtCore.QRect(0, 0, 559+hoffset, 342+voffset)
self.bmpname = whoami()
# }}}
def test_theme_font(self):
t = Theme(u'blank_theme.xml')
t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,64)
t.Name = "font"
t.FontName = "Times New Roman"
self.renderer.set_theme(t)
self.answer = self.renderer.render_screen(0)
self.expected_answer = QtCore.QRect(0, 0, 499, 336)
self.bmpname=whoami()
if __name__ == "__main__":
test_render_theme = TestRenderTheme()
test_render_theme.setup_class()
test_render_theme.setup_method(None)
test_render_theme.test_bg_stretch_y()
test_render_theme.teardown_method(None)

View File

@ -1,13 +0,0 @@
from openlp.core.lib import Plugin
import logging
class testplugin3toodeep(Plugin):
name="testplugin3"
version=0
global log
log=logging.getLogger(u'testplugin1')
log.info(u'Started')
weight=10
def __init__(self):
pass

View File

@ -1,13 +0,0 @@
from openlp.core.lib import Plugin
import logging
class testplugin1(Plugin):
name="testplugin1"
version=0
global log
log=logging.getLogger(u'testplugin1')
log.info(u'Started')
weight=10
def __init__(self):
pass

View File

@ -1,8 +0,0 @@
from openlp.core.lib import Plugin
class testplugin2(Plugin):
name="testplugin2"
version=1
weight=1
def __init__(self):
pass

View File

@ -5,8 +5,9 @@
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Martin Thompson, Tim Bentley, Carsten #
# Tinggaard, Jon Tibble, Jonathan Corwin, Maikel Stuivenberg, Scott Guerrieri #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -22,4 +23,4 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from theme import Theme
from theme import Theme

View File

@ -1,57 +0,0 @@
import os
import os.path
import sys
from PyQt4 import QtGui
from openlp.core.theme import Theme
mypath = os.path.split(os.path.abspath(__file__))[0]
sys.path.insert(0, (os.path.join(mypath, '..', '..', '..', '..')))
print sys.path
def test_read_theme():
dir = os.path.split(__file__)[0]
# test we can read a theme
theme = Theme(os.path.join(dir, 'test_theme.xml'))
print theme
assert(theme.BackgroundParameter1 == 'sunset1.jpg')
assert(theme.BackgroundParameter2 is None)
assert(theme.BackgroundParameter3 is None)
assert(theme.BackgroundType == 2)
assert(theme.FontColor == QtGui.QColor(255,255,255))
assert(theme.FontName == 'Tahoma')
assert(theme.FontProportion == 16)
assert(theme.FontUnits == 'pixels')
assert(theme.HorizontalAlign == 2)
assert(theme.Name == 'openlp.org Packaged Theme')
assert(theme.Outline == -1)
assert(theme.OutlineColor == QtGui.QColor(255,0,0))
assert(theme.Shadow == -1)
assert(theme.ShadowColor == QtGui.QColor(0,0,1))
assert(theme.VerticalAlign == 0)
def test_theme():
# test we create a "blank" theme correctly
theme = Theme()
print theme
assert(theme.BackgroundParameter1 == QtGui.QColor(0,0,0))
assert(theme.BackgroundParameter2 is None)
assert(theme.BackgroundParameter3 is None)
assert(theme.BackgroundType == 0)
assert(theme.FontColor == QtGui.QColor(255,255,255))
assert(theme.FontName == 'Arial')
assert(theme.FontProportion == 30)
assert(theme.HorizontalAlign == 0)
assert(theme.FontUnits == 'pixels')
assert(theme.Name == 'BlankStyle')
assert(theme.Outline == 0)
assert(theme.Shadow == 0)
assert(theme.VerticalAlign == 0)
print "Tests passed"
if __name__ == "__main__":
test_read_theme()
test_theme()

View File

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<Theme>
<Name>openlp.org Packaged Theme</Name>
<BackgroundType>2</BackgroundType>
<BackgroundParameter1>sunset1.jpg</BackgroundParameter1>
<BackgroundParameter2/>
<BackgroundParameter3/>
<FontName>Tahoma</FontName>
<FontColor>clWhite</FontColor>
<FontProportion>16</FontProportion>
<FontUnits>pixels</FontUnits>
<Shadow>-1</Shadow>
<ShadowColor>$00000001</ShadowColor>
<Outline>-1</Outline>
<OutlineColor>clRed</OutlineColor>
<HorizontalAlign>2</HorizontalAlign>
<VerticalAlign>0</VerticalAlign>
</Theme>

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -149,4 +149,4 @@ class Theme(object):
for key in dir(self):
if key[0:1] != u'_':
theme_strings.append(u'%30s : %s' % (key, getattr(self, key)))
return u'\n'.join(theme_strings)
return u'\n'.join(theme_strings)

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -23,9 +23,13 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from serviceitemform import ServiceItemNoteForm
from slidecontroller import HideMode
from servicenoteform import ServiceNoteForm
from serviceitemeditform import ServiceItemEditForm
from screen import ScreenList
from maindisplay import MainDisplay
from maindisplay import VideoDisplay
from maindisplay import DisplayManager
from amendthemeform import AmendThemeForm
from slidecontroller import SlideController
from splashscreen import SplashScreen
@ -41,4 +45,4 @@ from mainwindow import MainWindow
__all__ = ['SplashScreen', 'AboutForm', 'SettingsForm', 'MainWindow',
'MainDisplay', 'SlideController', 'ServiceManager', 'ThemeManager',
'AmendThemeForm', 'MediaDockManager', 'ServiceItemNoteForm']
'AmendThemeForm', 'MediaDockManager', 'ServiceItemEditForm']

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -115,7 +115,7 @@ class Ui_AboutDialog(object):
def retranslateUi(self, AboutDialog):
AboutDialog.setWindowTitle(self.trUtf8('About OpenLP'))
self.AboutTextEdit.setPlainText(self.trUtf8(
'OpenLP <version> build <revision> - Open Source Lyrics '
'OpenLP <version><revision> - Open Source Lyrics '
'Projection\n'
'\n'
'OpenLP is free church presentation software, or lyrics '
@ -142,24 +142,36 @@ class Ui_AboutDialog(object):
' Michael "cocooncrash" Gorven\n'
' Scott "sguerrieri" Guerrieri\n'
' Raoul "superfly" Snyman\n'
' Maikel Stuivenberg\n'
' Martin "mijiti" Thompson\n'
' Jon "Meths" Tibble\n'
'\n'
'Contributors\n'
' Meinert "m2j" Jordan\n'
' Christian "crichter" Richter\n'
' Maikel Stuivenberg\n'
' Carsten "catini" Tingaard\n'
'\n'
'Testers\n'
' Wesley "wrst" Stout'
' Philip "Phill" Ridout\n'
' Wesley "wrst" Stout (lead)\n'
'\n'
'Packagers\n'
' Thomas "tabthorpe" Abthorpe (FreeBSD)\n'
' Tim "TRB143" Bentley (Fedora)\n'
' Michael "cocooncrash" Gorven (Ubuntu)\n'
' Matthias "matthub" Hub (Mac OS X)\n'
' Raoul "superfly" Snyman (Windows)\n'
))
self.AboutNotebook.setTabText(
self.AboutNotebook.indexOf(self.CreditsTab),
self.trUtf8('Credits'))
self.LicenseTextEdit.setPlainText(self.trUtf8(
'Copyright ' + u'\u00a9'.encode('utf8') + ' 2004-2009 Raoul '
'Copyright ' + u'\u00a9'.encode('utf8') + ' 2004-2010 Raoul '
'Snyman\n'
'Portions copyright ' + u'\u00a9'.encode('utf8') + ' 2004-2009 '
'Portions copyright ' + u'\u00a9'.encode('utf8') + ' 2004-2010 '
'Tim Bentley, Jonathan Corwin, Michael Gorven, Scott Guerrieri, '
'Maikel Stuivenberg, Martin Thompson, Jon Tibble, Carsten '
'Tinggaard\n'
'Christian Richter, Maikel Stuivenberg, Martin Thompson, Jon '
'Tibble, Carsten Tinggaard\n'
'\n'
'This program is free software; you can redistribute it and/or '
'modify it under the terms of the GNU General Public License as '

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -39,11 +39,16 @@ class AboutForm(QtGui.QDialog, Ui_AboutDialog):
QtGui.QDialog.__init__(self, parent)
self.applicationVersion = applicationVersion
self.setupUi(self)
self.AboutTextEdit.setPlainText(
self.AboutTextEdit.toPlainText()\
.replace(u'<version>', self.applicationVersion[u'version'])\
.replace(u'<revision>', self.applicationVersion[u'build'])
)
about_text = self.AboutTextEdit.toPlainText()
about_text = about_text.replace(u'<version>',
self.applicationVersion[u'version'])
if self.applicationVersion[u'build']:
build_text = u' %s %s' % (self.trUtf8('build'),
self.applicationVersion[u'build'])
else:
build_text = u''
about_text = about_text.replace(u'<revision>', build_text)
self.AboutTextEdit.setPlainText(about_text)
QtCore.QObject.connect(self.ContributeButton,
QtCore.SIGNAL(u'clicked()'), self.onContributeButtonClicked)
@ -53,4 +58,4 @@ class AboutForm(QtGui.QDialog, Ui_AboutDialog):
"""
import webbrowser
url = u'http://www.openlp.org/en/documentation/introduction/contributing.html'
webbrowser.open_new(url)
webbrowser.open_new(url)

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -116,7 +116,7 @@ class Ui_AmendThemeDialog(object):
self.ImageLineEdit.setObjectName(u'ImageLineEdit')
self.horizontalLayout_2.addWidget(self.ImageLineEdit)
self.ImageToolButton = QtGui.QToolButton(self.ImageFilenameWidget)
icon1 = build_icon(u':/images/image_load.png')
icon1 = build_icon(u':/general/general_open.png')
self.ImageToolButton.setIcon(icon1)
self.ImageToolButton.setObjectName(u'ImageToolButton')
self.horizontalLayout_2.addWidget(self.ImageToolButton)
@ -685,4 +685,4 @@ class Ui_AmendThemeDialog(object):
self.ThemeTabWidget.setTabText(
self.ThemeTabWidget.indexOf(self.OtherOptionsTab),
self.trUtf8('Other Options'))
self.PreviewGroupBox.setTitle(self.trUtf8('Preview'))
self.PreviewGroupBox.setTitle(self.trUtf8('Preview'))

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -393,6 +393,7 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.theme.background_type = u'solid'
if self.theme.background_color is None :
self.theme.background_color = u'#000000'
self.ImageLineEdit.setText(u'')
elif background == 1: # Gradient
self.theme.background_type = u'gradient'
if gradient == 0: # Horizontal
@ -405,6 +406,7 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.theme.background_startColor = u'#000000'
if self.theme.background_endColor is None :
self.theme.background_endColor = u'#ff0000'
self.ImageLineEdit.setText(u'')
else:
self.theme.background_type = u'image'
self.stateChanging(self.theme)
@ -422,7 +424,6 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.Color1PushButton.setStyleSheet(
u'background-color: %s' % \
unicode(self.theme.background_startColor))
self.previewTheme()
def onColor2PushButtonClicked(self):
@ -561,22 +562,18 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
u'background-color: %s' % unicode(theme.font_main_color))
self.FontFooterColorPushButton.setStyleSheet(
u'background-color: %s' % unicode(theme.font_footer_color))
if not self.theme.font_main_override:
self.FontMainDefaultCheckBox.setChecked(True)
else:
self.FontMainDefaultCheckBox.setChecked(False)
if not self.theme.font_footer_override:
self.FontFooterDefaultCheckBox.setChecked(True)
else:
self.FontFooterDefaultCheckBox.setChecked(False)
self.OutlineColorPushButton.setStyleSheet(
u'background-color: %s' % unicode(theme.display_outline_color))
self.ShadowColorPushButton.setStyleSheet(
u'background-color: %s' % unicode(theme.display_shadow_color))
if self.theme.display_outline:
self.OutlineCheckBox.setChecked(True)
self.OutlineColorPushButton.setEnabled(True)
@ -584,7 +581,6 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.OutlineCheckBox.setChecked(False)
self.OutlineColorPushButton.setEnabled(False)
self.OutlineSpinBox.setValue(int(self.theme.display_outline_size))
if self.theme.display_shadow:
self.ShadowCheckBox.setChecked(True)
self.ShadowColorPushButton.setEnabled(True)
@ -592,12 +588,10 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.ShadowCheckBox.setChecked(False)
self.ShadowColorPushButton.setEnabled(False)
self.ShadowSpinBox.setValue(int(self.theme.display_shadow_size))
if self.theme.display_slideTransition:
self.SlideTransitionCheckedBox.setCheckState(QtCore.Qt.Checked)
else:
self.SlideTransitionCheckedBox.setCheckState(QtCore.Qt.Unchecked)
self.HorizontalComboBox.setCurrentIndex(
self.theme.display_horizontalAlign)
self.VerticalComboBox.setCurrentIndex(self.theme.display_verticalAlign)
@ -657,7 +651,6 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.ImageFilenameWidget.setVisible(True)
self.GradientLabel.setVisible(False)
self.GradientComboBox.setVisible(False)
if not theme.font_main_override:
self.FontMainXSpinBox.setEnabled(False)
self.FontMainYSpinBox.setEnabled(False)

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -25,16 +25,29 @@
from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab, str_to_bool
from openlp.core.lib import SettingsTab, str_to_bool, Receiver
class GeneralTab(SettingsTab):
"""
GeneralTab is the general settings tab in the settings dialog.
"""
def __init__(self, screen_list):
self.screen_list = screen_list
def __init__(self, screens):
self.screens = screens
SettingsTab.__init__(self, u'General')
def preLoad(self):
"""
Set up the display screen and set correct screen
values.
If not set before default to last screen.
"""
self.MonitorNumber = int(self.config.get_config(u'monitor',
self.screens.monitor_number))
self.screens.set_current_display(self.MonitorNumber)
self.screens.monitor_number = self.MonitorNumber
self.DisplayOnMonitor = str_to_bool(self.config.get_config(u'display on monitor', u'True'))
self.screens.display = self.DisplayOnMonitor
def setupUi(self):
self.setObjectName(u'GeneralTab')
self.tabTitleVisible = self.trUtf8('General')
@ -60,6 +73,10 @@ class GeneralTab(SettingsTab):
self.MonitorComboBox = QtGui.QComboBox(self.MonitorGroupBox)
self.MonitorComboBox.setObjectName(u'MonitorComboBox')
self.MonitorLayout.addWidget(self.MonitorComboBox)
self.MonitorLayout.addWidget(self.MonitorComboBox)
self.DisplayOnMonitorCheck = QtGui.QCheckBox(self.MonitorGroupBox)
self.DisplayOnMonitorCheck.setObjectName(u'MonitorComboBox')
self.MonitorLayout.addWidget(self.DisplayOnMonitorCheck)
self.GeneralLeftLayout.addWidget(self.MonitorGroupBox)
self.StartupGroupBox = QtGui.QGroupBox(self.GeneralLeftWidget)
self.StartupGroupBox.setObjectName(u'StartupGroupBox')
@ -133,6 +150,8 @@ class GeneralTab(SettingsTab):
self.GeneralLayout.addWidget(self.GeneralRightWidget)
QtCore.QObject.connect(self.MonitorComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onMonitorComboBoxChanged)
QtCore.QObject.connect(self.DisplayOnMonitorCheck,
QtCore.SIGNAL(u'stateChanged(int)'), self.onDisplayOnMonitorCheckChanged)
QtCore.QObject.connect(self.WarningCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), self.onWarningCheckBoxChanged)
QtCore.QObject.connect(self.AutoOpenCheckBox,
@ -153,6 +172,7 @@ class GeneralTab(SettingsTab):
def retranslateUi(self):
self.MonitorGroupBox.setTitle(self.trUtf8('Monitors'))
self.MonitorLabel.setText(self.trUtf8('Select monitor for output display:'))
self.DisplayOnMonitorCheck.setText(self.trUtf8('Display if in single screen'))
self.StartupGroupBox.setTitle(self.trUtf8('Application Startup'))
self.WarningCheckBox.setText(self.trUtf8('Show blank screen warning'))
self.AutoOpenCheckBox.setText(self.trUtf8('Automatically open the last service'))
@ -168,6 +188,9 @@ class GeneralTab(SettingsTab):
def onMonitorComboBoxChanged(self):
self.MonitorNumber = self.MonitorComboBox.currentIndex()
def onDisplayOnMonitorCheckChanged(self, value):
self.DisplayOnMonitor = (value == QtCore.Qt.Checked)
def onAutoOpenCheckBoxChanged(self, value):
self.AutoOpen = (value == QtCore.Qt.Checked)
@ -193,13 +216,12 @@ class GeneralTab(SettingsTab):
self.Password = self.PasswordEdit.displayText()
def load(self):
for screen in self.screen_list.screen_list:
for screen in self.screens.screen_list:
screen_name = u'%s %d' % (self.trUtf8('Screen'), screen[u'number'] + 1)
if screen[u'primary']:
screen_name = u'%s (%s)' % (screen_name, self.trUtf8('primary'))
self.MonitorComboBox.addItem(screen_name)
# Get the configs
self.MonitorNumber = int(self.config.get_config(u'monitor', u'0'))
self.Warning = str_to_bool(self.config.get_config(u'blank warning', u'False'))
self.AutoOpen = str_to_bool(self.config.get_config(u'auto open', u'False'))
self.ShowSplash = str_to_bool(self.config.get_config(u'show splash', u'True'))
@ -211,6 +233,7 @@ class GeneralTab(SettingsTab):
self.SaveCheckServiceCheckBox.setChecked(self.PromptSaveService)
# Set a few things up
self.MonitorComboBox.setCurrentIndex(self.MonitorNumber)
self.DisplayOnMonitorCheck.setChecked(self.DisplayOnMonitor)
self.WarningCheckBox.setChecked(self.Warning)
self.AutoOpenCheckBox.setChecked(self.AutoOpen)
self.ShowSplashCheckBox.setChecked(self.ShowSplash)
@ -221,6 +244,7 @@ class GeneralTab(SettingsTab):
def save(self):
self.config.set_config(u'monitor', self.MonitorNumber)
self.config.set_config(u'display on monitor', self.DisplayOnMonitor)
self.config.set_config(u'blank warning', self.Warning)
self.config.set_config(u'auto open', self.AutoOpen)
self.config.set_config(u'show splash', self.ShowSplash)
@ -229,3 +253,9 @@ class GeneralTab(SettingsTab):
self.config.set_config(u'ccli number', self.CCLINumber)
self.config.set_config(u'songselect username', self.Username)
self.config.set_config(u'songselect password', self.Password)
self.screens.display = self.DisplayOnMonitor
#Monitor Number has changed.
if self.screens.monitor_number != self.MonitorNumber:
self.screens.monitor_number = self.MonitorNumber
self.screens.set_current_display(self.MonitorNumber)
Receiver.send_message(u'screen_changed')

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -30,9 +30,32 @@ from PyQt4 import QtCore, QtGui
from PyQt4.phonon import Phonon
from openlp.core.lib import Receiver, resize_image
from openlp.core.ui import HideMode
log = logging.getLogger(__name__)
class DisplayManager(QtGui.QWidget):
"""
Wrapper class to hold the display widgets.
I will provide API's in future to access the screens allow for
extra displays to be added.
"""
def __init__(self, screens):
QtGui.QWidget.__init__(self)
self.screens = screens
self.videoDisplay = VideoDisplay(self, screens)
self.mainDisplay = MainDisplay(self, screens)
def setup(self):
self.videoDisplay.setup()
self.mainDisplay.setup()
def close(self):
self.videoDisplay.close()
self.mainDisplay.close()
class DisplayWidget(QtGui.QWidget):
"""
Customised version of QTableWidget which can respond to keyboard
@ -41,7 +64,7 @@ class DisplayWidget(QtGui.QWidget):
log.info(u'MainDisplay loaded')
def __init__(self, parent=None, name=None):
QtGui.QWidget.__init__(self, parent)
QtGui.QWidget.__init__(self, None)
self.parent = parent
self.hotkey_map = {QtCore.Qt.Key_Return: 'servicemanager_next_item',
QtCore.Qt.Key_Space: 'live_slidecontroller_next_noloop',
@ -91,16 +114,11 @@ class MainDisplay(DisplayWidget):
The list of screens.
"""
log.debug(u'Initilisation started')
DisplayWidget.__init__(self, None)
DisplayWidget.__init__(self, parent)
self.parent = parent
self.setWindowTitle(u'OpenLP Display')
self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
self.screens = screens
self.mediaObject = Phonon.MediaObject(self)
self.video = Phonon.VideoWidget()
self.video.setVisible(False)
self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject)
Phonon.createPath(self.mediaObject, self.video)
Phonon.createPath(self.mediaObject, self.audio)
self.display_image = QtGui.QLabel(self)
self.display_image.setScaledContents(True)
self.display_text = QtGui.QLabel(self)
@ -112,36 +130,26 @@ class MainDisplay(DisplayWidget):
self.blankFrame = None
self.frame = None
self.firstTime = True
self.mediaLoaded = False
self.hasTransition = False
self.mediaBackground = False
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'live_slide_hide'), self.hideDisplay)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'live_slide_show'), self.showDisplay)
QtCore.QObject.connect(self.mediaObject,
QtCore.SIGNAL(u'finished()'), self.onMediaFinish)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_start'), self.onMediaQueue)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_play'), self.onMediaPlay)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_pause'), self.onMediaPause)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_stop'), self.onMediaStop)
QtCore.SIGNAL(u'media_start'), self.hideDisplay)
def setup(self, screenNumber):
def setup(self):
"""
Sets up the screen on a particular screen.
@param (integer) screen This is the screen number.
"""
log.debug(u'Setup %s for %s ' %(self.screens, screenNumber))
log.debug(u'Setup %s for %s ' %(self.screens,
self.screens.monitor_number))
self.setVisible(False)
self.screen = self.screens.current
#Sort out screen locations and sizes
self.setGeometry(self.screen[u'size'])
self.display_alert.setGeometry(self.screen[u'size'])
self.video.setGeometry(self.screen[u'size'])
self.display_image.resize(self.screen[u'size'].width(),
self.screen[u'size'].height())
self.display_text.resize(self.screen[u'size'].width(),
@ -168,13 +176,13 @@ class MainDisplay(DisplayWidget):
self.screen[u'size'].height(),
QtGui.QImage.Format_ARGB32_Premultiplied)
painter.begin(self.blankFrame)
#TODO make black when testing finished
painter.fillRect(self.blankFrame.rect(), QtCore.Qt.red)
painter.fillRect(self.blankFrame.rect(), QtCore.Qt.black)
#build a blank transparent image
self.transparent = QtGui.QPixmap(self.screen[u'size'].width(),
self.screen[u'size'].height())
self.transparent.fill(QtCore.Qt.transparent)
self.display_alert.setPixmap(self.transparent)
self.display_text.setPixmap(self.transparent)
self.frameView(self.transparent)
# To display or not to display?
if not self.screen[u'primary']:
@ -183,9 +191,9 @@ class MainDisplay(DisplayWidget):
else:
self.setVisible(False)
self.primary = True
Receiver.send_message(u'screen_changed')
def resetDisplay(self):
log.debug(u'resetDisplay')
Receiver.send_message(u'stop_display_loop')
if self.primary:
self.setVisible(False)
@ -193,32 +201,46 @@ class MainDisplay(DisplayWidget):
self.showFullScreen()
def hideDisplay(self):
self.mediaLoaded = True
self.setVisible(False)
log.debug(u'hideDisplay')
self.display_image.setPixmap(self.transparent)
self.display_alert.setPixmap(self.transparent)
self.display_text.setPixmap(self.transparent)
self.moveToTop()
def moveToTop(self):
log.debug(u'moveToTop')
self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint \
| QtCore.Qt.FramelessWindowHint | QtCore.Qt.Dialog)
self.show()
def showDisplay(self):
self.mediaLoaded = False
log.debug(u'showDisplay')
if not self.primary:
self.setVisible(True)
self.showFullScreen()
Receiver.send_message(u'flush_alert')
def addImageWithText(self, frame):
log.debug(u'addImageWithText')
frame = resize_image(frame,
self.screen[u'size'].width(),
self.screen[u'size'].height() )
self.display_image.setPixmap(QtGui.QPixmap.fromImage(frame))
self.moveToTop()
def setAlertSize(self, top, height):
log.debug(u'setAlertSize')
self.display_alert.setGeometry(
QtCore.QRect(0, top,
self.screen[u'size'].width(), height))
def addAlertImage(self, frame, blank=False):
log.debug(u'addAlertImage')
if blank:
self.display_alert.setPixmap(self.transparent)
else:
self.display_alert.setPixmap(frame)
self.moveToTop()
def frameView(self, frame, transition=False):
"""
@ -227,6 +249,7 @@ class MainDisplay(DisplayWidget):
``frame``
Image frame to be rendered
"""
log.debug(u'frameView %d' % (self.displayBlank))
if not self.displayBlank:
if transition:
if self.frame is not None:
@ -246,63 +269,123 @@ class MainDisplay(DisplayWidget):
else:
self.display_text.setPixmap(QtGui.QPixmap.fromImage(frame))
self.display_frame = frame
if not self.isVisible():
if not self.isVisible() and self.screens.display:
self.setVisible(True)
self.showFullScreen()
else:
self.waitingFrame = frame
self.waitingFrameTrans = transition
def blankDisplay(self, blanked=True):
def blankDisplay(self, blankType=HideMode.Blank, blanked=True):
log.debug(u'Blank main Display %d' % blanked)
if blanked:
self.displayBlank = True
self.display_text.setPixmap(QtGui.QPixmap.fromImage(self.blankFrame))
if blankType == HideMode.Blank:
self.display_text.setPixmap(QtGui.QPixmap.fromImage(self.blankFrame))
elif blankType == HideMode.Theme:
theme = self.parent.RenderManager.renderer.bg_frame
if not theme:
theme = self.blankFrame
self.display_text.setPixmap(QtGui.QPixmap.fromImage(theme))
self.waitingFrame = None
self.waitingFrameTrans = False
else:
self.displayBlank = False
if self.display_frame:
if self.waitingFrame:
self.frameView(self.waitingFrame, self.waitingFrameTrans)
elif self.display_frame:
self.frameView(self.display_frame)
def onMediaQueue(self, message):
log.debug(u'Queue new media message %s' % message)
self.display_image.close()
self.display_text.close()
self.display_alert.close()
file = os.path.join(message[1], message[2])
if self.firstTime:
self.mediaObject.setCurrentSource(Phonon.MediaSource(file))
self.firstTime = False
class VideoDisplay(Phonon.VideoWidget):
"""
This is the form that is used to display videos on the projector.
"""
log.info(u'VideoDisplay Loaded')
def __init__(self, parent, screens,
aspect=Phonon.VideoWidget.AspectRatioWidget):
"""
The constructor for the display form.
``parent``
The parent widget.
``screens``
The list of screens.
"""
log.debug(u'VideoDisplay Initilisation started')
Phonon.VideoWidget.__init__(self)
self.setWindowTitle(u'OpenLP Video Display')
self.parent = parent
self.screens = screens
self.mediaObject = Phonon.MediaObject()
self.setAspectRatio(aspect)
self.audioObject = Phonon.AudioOutput(Phonon.VideoCategory)
Phonon.createPath(self.mediaObject, self)
Phonon.createPath(self.mediaObject, self.audioObject)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_start'), self.onMediaQueue)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_play'), self.onMediaPlay)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_pause'), self.onMediaPause)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_stop'), self.onMediaStop)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'update_config'), self.setup)
def keyPressEvent(self, event):
if type(event) == QtGui.QKeyEvent:
#here accept the event and do something
if event.key() == QtCore.Qt.Key_Escape:
self.onMediaStop()
event.accept()
event.ignore()
else:
self.mediaObject.enqueue(Phonon.MediaSource(file))
event.ignore()
def setup(self):
"""
Sets up the screen on a particular screen.
"""
log.debug(u'VideoDisplay Setup %s for %s ' %(self.screens,
self.screens.monitor_number))
self.setVisible(False)
self.screen = self.screens.current
#Sort out screen locations and sizes
self.setGeometry(self.screen[u'size'])
# To display or not to display?
if not self.screen[u'primary']:
self.showFullScreen()
self.primary = False
else:
self.setVisible(False)
self.primary = True
def onMediaQueue(self, message):
log.debug(u'VideoDisplay Queue new media message %s' % message)
file = os.path.join(message[1], message[2])
source = self.mediaObject.setCurrentSource(Phonon.MediaSource(file))
self.onMediaPlay()
def onMediaPlay(self):
log.debug(u'Play the new media, Live ')
if not self.mediaLoaded and not self.displayBlank:
self.blankDisplay()
self.display_frame = self.blankFrame
self.firstTime = True
self.mediaLoaded = True
self.display_image.hide()
self.display_text.hide()
self.display_alert.hide()
self.video.setFullScreen(True)
self.video.setVisible(True)
log.debug(u'VideoDisplay Play the new media, Live ')
self.mediaObject.play()
self.setVisible(True)
self.hide()
self.showFullScreen()
def onMediaPause(self):
log.debug(u'Media paused by user')
log.debug(u'VideoDisplay Media paused by user')
self.mediaObject.pause()
self.show()
def onMediaStop(self):
log.debug(u'Media stopped by user')
log.debug(u'VideoDisplay Media stopped by user')
self.mediaObject.stop()
self.onMediaFinish()
def onMediaFinish(self):
log.debug(u'Reached end of media playlist')
self.mediaObject.stop()
log.debug(u'VideoDisplay Reached end of media playlist')
self.mediaObject.clearQueue()
self.mediaLoaded = False
self.video.setVisible(False)
self.display_text.show()
self.display_image.show()
self.blankDisplay(False)
self.setVisible(False)

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -23,15 +23,14 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
import os
import logging
import time
from PyQt4 import QtCore, QtGui
from openlp.core.ui import AboutForm, SettingsForm, \
ServiceManager, ThemeManager, MainDisplay, SlideController, \
PluginForm, MediaDockManager
ServiceManager, ThemeManager, SlideController, \
PluginForm, MediaDockManager, DisplayManager
from openlp.core.lib import RenderManager, PluginConfig, build_icon, \
OpenLPDockWidget, SettingsManager, PluginManager, Receiver, str_to_bool
from openlp.core.utils import check_latest_version, AppLocation
@ -68,13 +67,13 @@ class VersionThread(QtCore.QThread):
"""
Run the thread.
"""
time.sleep(2)
time.sleep(1)
Receiver.send_message(u'blank_check')
version = check_latest_version(self.generalConfig, self.app_version)
#new version has arrived
if version != self.app_version:
if version != self.app_version[u'full']:
Receiver.send_message(u'version_check', u'%s' % version)
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
"""
@ -419,7 +418,7 @@ class Ui_MainWindow(object):
self.LanguageEnglishItem.setText(self.trUtf8('English'))
self.LanguageEnglishItem.setStatusTip(
self.trUtf8('Set the interface language to English'))
self.ToolsAddToolItem.setText(self.trUtf8('&Add Tool...'))
self.ToolsAddToolItem.setText(self.trUtf8('Add &Tool...'))
self.ToolsAddToolItem.setStatusTip(
self.trUtf8('Add an application to the list of tools'))
self.action_Preview_Panel.setText(self.trUtf8('&Preview Pane'))
@ -443,7 +442,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.serviceNotSaved = False
self.settingsmanager = SettingsManager(screens)
self.generalConfig = PluginConfig(u'General')
self.mainDisplay = MainDisplay(self, screens)
self.displayManager = DisplayManager(screens)
self.aboutForm = AboutForm(self, applicationVersion)
self.settingsForm = SettingsForm(self.screens, self, self)
# Set up the path with plugins
@ -494,6 +493,12 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.SIGNAL(u'update_global_theme'), self.defaultThemeChanged)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'version_check'), self.versionCheck)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'blank_check'), self.blankCheck)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'screen_changed'), self.screenChanged)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'status_message'), self.showStatusMessage)
QtCore.QObject.connect(self.FileNewItem,
QtCore.SIGNAL(u'triggered()'),
self.ServiceManagerContents.onNewService)
@ -510,7 +515,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
#RenderManager needs to call ThemeManager and
#ThemeManager needs to call RenderManager
self.RenderManager = RenderManager(self.ThemeManagerContents,
self.screens, self.getMonitorNumber())
self.screens)
#Define the media Dock Manager
self.mediaDockManager = MediaDockManager(self.MediaToolBox)
log.info(u'Load Plugins')
@ -521,7 +526,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.plugin_helpers[u'service'] = self.ServiceManagerContents
self.plugin_helpers[u'settings'] = self.settingsForm
self.plugin_helpers[u'toolbox'] = self.mediaDockManager
self.plugin_helpers[u'maindisplay'] = self.mainDisplay
self.plugin_helpers[u'maindisplay'] = self.displayManager.mainDisplay
self.plugin_manager.find_plugins(pluginpath, self.plugin_helpers)
# hook methods have to happen after find_plugins. Find plugins needs
# the controllers hence the hooks have moved from setupUI() to here
@ -550,39 +555,36 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
def versionCheck(self, version):
"""
Checks the version of the Application called from openlp.pyw
Triggered by delay thread.
"""
app_version = self.applicationVersion[u'full']
version_text = unicode(self.trUtf8('OpenLP version %s has been updated '
'to version %s\n\nYou can obtain the latest version from http://openlp.org'))
version_text = unicode(self.trUtf8('Version %s of OpenLP is now '
'available for download (you are currently running version %s).'
'\n\nYou can download the latest version from http://openlp.org'))
QtGui.QMessageBox.question(self,
self.trUtf8('OpenLP Version Updated'),
version_text % (app_version, version),
version_text % (version, app_version),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok),
QtGui.QMessageBox.Ok)
def getMonitorNumber(self):
"""
Set up the default behaviour of the monitor configuration in
here. Currently it is set to default to monitor 0 if the saved
monitor number does not exist.
"""
screen_number = int(self.generalConfig.get_config(u'monitor', 0))
if not self.screens.screen_exists(screen_number):
screen_number = 0
return screen_number
def show(self):
"""
Show the main form, as well as the display form
"""
self.showMaximized()
screen_number = self.getMonitorNumber()
self.mainDisplay.setup(screen_number)
if self.mainDisplay.isVisible():
self.mainDisplay.setFocus()
#screen_number = self.getMonitorNumber()
self.displayManager.setup()
if self.displayManager.mainDisplay.isVisible():
self.displayManager.mainDisplay.setFocus()
self.activateWindow()
if str_to_bool(self.generalConfig.get_config(u'auto open', False)):
self.ServiceManagerContents.onLoadService(True)
def blankCheck(self):
"""
Check and display message if screen blank on setup.
Triggered by delay thread.
"""
if str_to_bool(self.generalConfig.get_config(u'screen blank', False)) \
and str_to_bool(self.generalConfig.get_config(u'blank warning', False)):
self.LiveController.onBlankDisplay(True)
@ -593,8 +595,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtGui.QMessageBox.Ok)
def versionThread(self):
app_version = self.applicationVersion[u'full']
vT = VersionThread(self, app_version, self.generalConfig)
"""
Start an initial setup thread to delay notifications
"""
vT = VersionThread(self, self.applicationVersion, self.generalConfig)
vT.start()
def onHelpAboutItemClicked(self):
@ -616,11 +620,15 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
Show the Settings dialog
"""
self.settingsForm.exec_()
updated_display = self.getMonitorNumber()
if updated_display != self.screens.current_display:
self.screens.set_current_display(updated_display)
self.RenderManager.update_display(updated_display)
self.mainDisplay.setup(updated_display)
def screenChanged(self):
"""
The screen has changed to so tell the displays to update_display
their locations
"""
self.RenderManager.update_display()
self.displayManager.setup()
self.setFocus()
self.activateWindow()
def closeEvent(self, event):
@ -638,17 +646,14 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtGui.QMessageBox.Save)
if ret == QtGui.QMessageBox.Save:
self.ServiceManagerContents.onSaveService()
self.mainDisplay.close()
self.cleanUp()
event.accept()
elif ret == QtGui.QMessageBox.Discard:
self.mainDisplay.close()
self.cleanUp()
event.accept()
else:
event.ignore()
else:
self.mainDisplay.close()
self.cleanUp()
event.accept()
@ -661,10 +666,12 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
# Call the cleanup method to shutdown plugins.
log.info(u'cleanup plugins')
self.plugin_manager.finalise_plugins()
#Close down the displays
self.displayManager.close()
def serviceChanged(self, reset=False, serviceName=None):
"""
Hook to change the main window title when the service changes
Hook to change the main window title when the service chmainwindow.pyanges
``reset``
Shows if the service has been cleared or saved
@ -684,6 +691,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
title = u'%s - %s*' % (self.mainTitle, service_name)
self.setWindowTitle(title)
def showStatusMessage(self, message):
self.StatusBar.showMessage(message)
def defaultThemeChanged(self, theme):
self.DefaultThemeLabel.setText(
u'%s %s' % (self.defaultThemeText, theme))

View File

@ -6,15 +6,15 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 MERCHANdockILITY or #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -105,4 +105,4 @@ class Ui_PluginViewDialog(object):
self.AboutLabel.setText(self.trUtf8('About:'))
self.StatusLabel.setText(self.trUtf8('Status:'))
self.StatusComboBox.setItemText(0, self.trUtf8('Active'))
self.StatusComboBox.setItemText(1, self.trUtf8('Inactive'))
self.StatusComboBox.setItemText(1, self.trUtf8('Inactive'))

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -22,6 +22,7 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
import logging
log = logging.getLogger(__name__)
@ -36,14 +37,17 @@ class ScreenList(object):
self.preview = None
self.current = None
self.screen_list = []
self.count = 0
self.display_count = 0
#actual display number
self.current_display = 0
#save config display number
self.monitor_number = 0
def add_screen(self, screen):
if screen[u'primary']:
self.current = screen
self.screen_list.append(screen)
self.count += 1
self.display_count += 1
def screen_exists(self, number):
for screen in self.screen_list:
@ -52,21 +56,15 @@ class ScreenList(object):
return False
def set_current_display(self, number):
if number + 1 > self.count:
"""
Set up the current screen dimensions
"""
if number + 1 > self.display_count:
self.current = self.screen_list[0]
self.current_display = 0
else:
self.current = self.screen_list[number]
self.preview = self.current
self.current_display = number
if self.count == 1:
if self.display_count == 1:
self.preview = self.screen_list[0]
# if self.screen[u'number'] != screenNumber:
# # We will most probably never actually hit this bit, but just in
# # case the index in the list doesn't match the screen number, we
# # search for it.
# for scrn in self.screens:
# if scrn[u'number'] == screenNumber:
# self.screen = scrn
# break

View File

@ -0,0 +1,73 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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
class Ui_ServiceItemEditDialog(object):
def setupUi(self, ServiceItemEditDialog):
ServiceItemEditDialog.setObjectName(u'ServiceItemEditDialog')
ServiceItemEditDialog.resize(386, 272)
self.layoutWidget = QtGui.QWidget(ServiceItemEditDialog)
self.layoutWidget.setGeometry(QtCore.QRect(20, 20, 351, 241))
self.layoutWidget.setObjectName(u'layoutWidget')
self.outerLayout = QtGui.QVBoxLayout(self.layoutWidget)
self.outerLayout.setObjectName(u'outerLayout')
self.topLayout = QtGui.QHBoxLayout()
self.topLayout.setObjectName(u'topLayout')
self.listWidget = QtGui.QListWidget(self.layoutWidget)
self.listWidget.setAlternatingRowColors(True)
self.listWidget.setObjectName(u'listWidget')
self.topLayout.addWidget(self.listWidget)
self.buttonLayout = QtGui.QVBoxLayout()
self.buttonLayout.setObjectName(u'buttonLayout')
self.upButton = QtGui.QPushButton(self.layoutWidget)
self.upButton.setObjectName(u'upButton')
self.buttonLayout.addWidget(self.upButton)
spacerItem = QtGui.QSpacerItem(20, 40,
QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.buttonLayout.addItem(spacerItem)
self.deleteButton = QtGui.QPushButton(self.layoutWidget)
self.deleteButton.setObjectName(u'deleteButton')
self.buttonLayout.addWidget(self.deleteButton)
self.downButton = QtGui.QPushButton(self.layoutWidget)
self.downButton.setObjectName(u'downButton')
self.buttonLayout.addWidget(self.downButton)
self.topLayout.addLayout(self.buttonLayout)
self.outerLayout.addLayout(self.topLayout)
self.buttonBox = QtGui.QDialogButtonBox(self.layoutWidget)
self.buttonBox.setStandardButtons(
QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Save)
self.buttonBox.setObjectName(u'buttonBox')
self.outerLayout.addWidget(self.buttonBox)
self.retranslateUi(ServiceItemEditDialog)
QtCore.QMetaObject.connectSlotsByName(ServiceItemEditDialog)
def retranslateUi(self, ServiceItemEditDialog):
ServiceItemEditDialog.setWindowTitle(self.trUtf8('Service Item Maintenance'))
self.upButton.setText(self.trUtf8('Up'))
self.deleteButton.setText(self.trUtf8('Delete'))
self.downButton.setText(self.trUtf8('Down'))

View File

@ -0,0 +1,116 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 serviceitemeditdialog import Ui_ServiceItemEditDialog
class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
"""
This is the form that is used to edit the verses of the song.
"""
def __init__(self, parent=None):
"""
Constructor
"""
QtGui.QDialog.__init__(self, parent)
self.setupUi(self)
self.itemList = []
# enable drop
QtCore.QObject.connect(self.upButton,
QtCore.SIGNAL(u'clicked()'),
self.onItemUp)
QtCore.QObject.connect(self.downButton,
QtCore.SIGNAL(u'clicked()'),
self.onItemDown)
QtCore.QObject.connect(self.deleteButton,
QtCore.SIGNAL(u'clicked()'),
self.onItemDelete)
QtCore.QObject.connect(self.buttonBox,
QtCore.SIGNAL(u'accepted()'),
self.accept)
QtCore.QObject.connect(self.buttonBox,
QtCore.SIGNAL(u'rejected()'),
self.reject)
def setServiceItem(self, item):
self.item = item
self.itemList = []
if self.item.is_image():
self.data = True
for frame in self.item._raw_frames:
self.itemList.append(frame)
self.loadData()
def getServiceItem(self):
if self.data:
self.item._raw_frames = []
if self.item.is_image():
for item in self.itemList:
self.item.add_from_image(item[u'path'],
item[u'title'], item[u'image'])
self.item.render()
return self.item
def loadData(self):
self.listWidget.clear()
for frame in self.itemList:
item_name = QtGui.QListWidgetItem(frame[u'title'])
self.listWidget.addItem(item_name)
def onItemDelete(self):
"""
Delete the selected row
"""
items = self.listWidget.selectedItems()
for item in items:
row = self.listWidget.row(item)
self.itemList.remove(self.itemList[row])
self.loadData()
def onItemUp(self):
"""
Move the selected row up in the list
"""
items = self.listWidget.selectedItems()
for item in items:
row = self.listWidget.row(item)
if row > 0:
temp = self.itemList[row]
self.itemList.remove(self.itemList[row])
self.itemList.insert(row - 1, temp)
self.loadData()
def onItemDown(self):
"""
Move the selected row down in the list
"""
items = self.listWidget.selectedItems()
for item in items:
row = self.listWidget.row(item)
if row < len(self.itemList) and row is not -1:
temp = self.itemList[row]
self.itemList.remove(self.itemList[row])
self.itemList.insert(row + 1, temp)
self.loadData()

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -33,8 +33,8 @@ log = logging.getLogger(__name__)
from PyQt4 import QtCore, QtGui
from openlp.core.lib import PluginConfig, OpenLPToolbar, ServiceItem, \
contextMenuAction, Receiver, str_to_bool, build_icon
from openlp.core.ui import ServiceItemNoteForm
contextMenuAction, Receiver, str_to_bool, build_icon, ItemCapabilities
from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm
class ServiceManagerList(QtGui.QTreeWidget):
@ -100,12 +100,14 @@ class ServiceManager(QtGui.QWidget):
self.parent = parent
self.serviceItems = []
self.serviceName = u''
self.droppos = 0
#is a new service and has not been saved
self.isNew = True
#Indicates if remoteTriggering is active. If it is the next addServiceItem call
#will replace the currently selected one.
self.remoteEditTriggered = False
self.serviceItemNoteForm = ServiceItemNoteForm()
self.serviceNoteForm = ServiceNoteForm()
self.serviceItemEditForm = ServiceItemEditForm()
#start with the layout
self.Layout = QtGui.QVBoxLayout(self)
self.Layout.setSpacing(0)
@ -113,13 +115,13 @@ class ServiceManager(QtGui.QWidget):
# Create the top toolbar
self.Toolbar = OpenLPToolbar(self)
self.Toolbar.addToolbarButton(
self.trUtf8('New Service'), u':/services/service_new.png',
self.trUtf8('New Service'), u':/general/general_new.png',
self.trUtf8('Create a new service'), self.onNewService)
self.Toolbar.addToolbarButton(
self.trUtf8('Open Service'), u':/services/service_open.png',
self.trUtf8('Open Service'), u':/general/general_open.png',
self.trUtf8('Load an existing service'), self.onLoadService)
self.Toolbar.addToolbarButton(
self.trUtf8('Save Service'), u':/services/service_save.png',
self.trUtf8('Save Service'), u':/general/general_save.png',
self.trUtf8('Save this service'), self.onSaveService)
self.Toolbar.addSeparator()
self.ThemeLabel = QtGui.QLabel(self.trUtf8('Theme:'),
@ -147,7 +149,8 @@ class ServiceManager(QtGui.QWidget):
self.ServiceManagerList.setHeaderHidden(True)
self.ServiceManagerList.setExpandsOnDoubleClick(False)
self.ServiceManagerList.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.ServiceManagerList.customContextMenuRequested.connect(self.contextMenu)
QtCore.QObject.connect(self.ServiceManagerList,
QtCore.SIGNAL('customContextMenuRequested(QPoint)'), self.contextMenu)
self.ServiceManagerList.setObjectName(u'ServiceManagerList')
# enable drop
self.ServiceManagerList.__class__.dragEnterEvent = self.dragEnterEvent
@ -170,7 +173,7 @@ class ServiceManager(QtGui.QWidget):
self.trUtf8('Move to end'), self.onServiceEnd)
self.OrderToolbar.addSeparator()
self.OrderToolbar.addToolbarButton(
self.trUtf8('&Delete From Service'), u':/services/service_delete.png',
self.trUtf8('&Delete From Service'), u':/general/general_delete.png',
self.trUtf8('Delete From Service'), self.onDeleteFromService)
self.Layout.addWidget(self.OrderToolbar)
# Connect up our signals and slots
@ -190,6 +193,8 @@ class ServiceManager(QtGui.QWidget):
QtCore.SIGNAL(u'presentation types'), self.onPresentationTypes)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'servicemanager_next_item'), self.nextItem)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_updated'), self.regenerateServiceItems)
# Last little bits of setting up
self.config = PluginConfig(u'ServiceManager')
self.servicePath = self.config.get_data_path()
@ -198,17 +203,19 @@ class ServiceManager(QtGui.QWidget):
#build the context menu
self.menu = QtGui.QMenu()
self.editAction = self.menu.addAction(self.trUtf8('&Edit Item'))
self.editAction.setIcon(build_icon(u':/services/service_edit.png'))
self.editAction.setIcon(build_icon(u':/general/general_edit.png'))
self.maintainAction = self.menu.addAction(self.trUtf8('&Maintain Item'))
self.editAction.setIcon(build_icon(u':/general/general_edit.png'))
self.notesAction = self.menu.addAction(self.trUtf8('&Notes'))
self.notesAction.setIcon(build_icon(u':/services/service_notes.png'))
self.deleteAction = self.menu.addAction(self.trUtf8('&Delete From Service'))
self.deleteAction.setIcon(build_icon(u':/services/service_delete.png'))
self.deleteAction.setIcon(build_icon(u':/general/general_delete.png'))
self.sep1 = self.menu.addAction(u'')
self.sep1.setSeparator(True)
self.previewAction = self.menu.addAction(self.trUtf8('&Preview Verse'))
self.previewAction.setIcon(build_icon(u':/system/system_preview.png'))
self.previewAction.setIcon(build_icon(u':/general/general_preview.png'))
self.liveAction = self.menu.addAction(self.trUtf8('&Live Verse'))
self.liveAction.setIcon(build_icon(u':/system/system_live.png'))
self.liveAction.setIcon(build_icon(u':/general/general_live.png'))
self.sep2 = self.menu.addAction(u'')
self.sep2.setSeparator(True)
self.themeMenu = QtGui.QMenu(self.trUtf8(u'&Change Item Theme'))
@ -216,15 +223,21 @@ class ServiceManager(QtGui.QWidget):
def contextMenu(self, point):
item = self.ServiceManagerList.itemAt(point)
if item is None:
return
if item.parent() is None:
pos = item.data(0, QtCore.Qt.UserRole).toInt()[0]
else:
pos = item.parent().data(0, QtCore.Qt.UserRole).toInt()[0]
serviceItem = self.serviceItems[pos - 1]
self.editAction.setVisible(False)
self.maintainAction.setVisible(False)
self.notesAction.setVisible(False)
if serviceItem[u'service_item'].edit_enabled:
if serviceItem[u'service_item'].is_capable(ItemCapabilities.AllowsEdit):
self.editAction.setVisible(True)
if serviceItem[u'service_item']\
.is_capable(ItemCapabilities.AllowsMaintain):
self.maintainAction.setVisible(True)
if item.parent() is None:
self.notesAction.setVisible(True)
self.themeMenu.menuAction().setVisible(False)
@ -233,6 +246,8 @@ class ServiceManager(QtGui.QWidget):
action = self.menu.exec_(self.ServiceManagerList.mapToGlobal(point))
if action == self.editAction:
self.remoteEdit()
if action == self.maintainAction:
self.onServiceItemEditForm()
if action == self.deleteAction:
self.onDeleteFromService()
if action == self.notesAction:
@ -247,11 +262,20 @@ class ServiceManager(QtGui.QWidget):
def onServiceItemNoteForm(self):
item, count = self.findServiceItem()
self.serviceItemNoteForm.textEdit.setPlainText(
self.serviceNoteForm.textEdit.setPlainText(
self.serviceItems[item][u'service_item'].notes)
if self.serviceItemNoteForm.exec_():
if self.serviceNoteForm.exec_():
self.serviceItems[item][u'service_item'].notes = \
self.serviceItemNoteForm.textEdit.toPlainText()
self.serviceNoteForm.textEdit.toPlainText()
self.repaintServiceList(item, 0)
def onServiceItemEditForm(self):
item, count = self.findServiceItem()
self.serviceItemEditForm.setServiceItem(
self.serviceItems[item][u'service_item'])
if self.serviceItemEditForm.exec_():
self.serviceItems[item][u'service_item'] = \
self.serviceItemEditForm.getServiceItem()
self.repaintServiceList(item, 0)
def nextItem(self):
@ -348,7 +372,7 @@ class ServiceManager(QtGui.QWidget):
def onServiceUp(self):
"""
Move the current ServiceItem up in the list
Note move up means move to top of area ie 0.
Note move up means move to top of area ie 0.
"""
item, count = self.findServiceItem()
if item > 0:
@ -472,7 +496,8 @@ class ServiceManager(QtGui.QWidget):
log.debug(u'onSaveService')
if not quick or self.isNew:
filename = QtGui.QFileDialog.getSaveFileName(self,
u'Save Service', self.config.get_last_dir())
self.trUtf8(u'Save Service'), self.config.get_last_dir(),
self.trUtf8(u'OpenLP Service Files (*.osz)'))
else:
filename = self.config.get_last_dir()
if filename:
@ -493,7 +518,7 @@ class ServiceManager(QtGui.QWidget):
if item[u'service_item'].uses_file():
for frame in item[u'service_item'].get_frames():
path_from = unicode(os.path.join(
item[u'service_item'].service_item_path,
frame[u'path'],
frame[u'title']))
zip.write(path_from)
file = open(servicefile, u'wb')
@ -511,9 +536,9 @@ class ServiceManager(QtGui.QWidget):
os.remove(servicefile)
except:
pass #if not present do not worry
name = filename.split(os.path.sep)
self.serviceName = name[-1]
self.parent.serviceChanged(True, self.serviceName)
name = filename.split(os.path.sep)
self.serviceName = name[-1]
self.parent.serviceChanged(True, self.serviceName)
def onQuickSaveService(self):
self.onSaveService(True)
@ -615,7 +640,7 @@ class ServiceManager(QtGui.QWidget):
for item in tempServiceItems:
self.addServiceItem(item[u'service_item'], False, item[u'expanded'])
#Set to False as items may have changed rendering
#does not impact the saved song so True may aslo be valid
#does not impact the saved song so True may also be valid
self.parent.serviceChanged(False, self.serviceName)
def addServiceItem(self, item, rebuild=False, expand=True):
@ -635,19 +660,27 @@ class ServiceManager(QtGui.QWidget):
self.repaintServiceList(sitem + 1, 0)
self.parent.LiveController.replaceServiceManagerItem(item)
else:
if sitem == -1:
self.serviceItems.append({u'service_item': item,
u'order': len(self.serviceItems) + 1,
u'expanded':expand})
#nothing selected for dnd
if self.droppos == 0:
if isinstance(item, list):
for inditem in item:
self.serviceItems.append({u'service_item': inditem,
u'order': len(self.serviceItems) + 1,
u'expanded':expand})
else:
self.serviceItems.append({u'service_item': item,
u'order': len(self.serviceItems) + 1,
u'expanded':expand})
self.repaintServiceList(len(self.serviceItems) + 1, 0)
else:
self.serviceItems.insert(sitem + 1, {u'service_item': item,
u'order': len(self.serviceItems)+1,
self.serviceItems.insert(self.droppos, {u'service_item': item,
u'order': self.droppos,
u'expanded':expand})
self.repaintServiceList(sitem + 1, 0)
self.repaintServiceList(self.droppos, 0)
#if rebuilding list make sure live is fixed.
if rebuild:
self.parent.LiveController.replaceServiceManagerItem(item)
self.droppos = 0
self.parent.serviceChanged(False, self.serviceName)
def makePreview(self):
@ -658,6 +691,17 @@ class ServiceManager(QtGui.QWidget):
self.parent.PreviewController.addServiceManagerItem(
self.serviceItems[item][u'service_item'], count)
def getServiceItem(self):
"""
Send the current item to the Preview slide controller
"""
item, count = self.findServiceItem()
if item == -1:
return False
else:
#Switch on remote edit update functionality.
self.remoteEditTriggered = True
return self.serviceItems[item][u'service_item']
def makeLive(self):
"""
@ -670,7 +714,7 @@ class ServiceManager(QtGui.QWidget):
get_config(u'auto preview', u'False')):
item += 1
if self.serviceItems and item < len(self.serviceItems) and \
self.serviceItems[item][u'service_item'].autoPreviewAllowed:
self.serviceItems[item][u'service_item'].is_capable(ItemCapabilities.AllowsPreview):
self.parent.PreviewController.addServiceManagerItem(
self.serviceItems[item][u'service_item'], 0)
@ -679,7 +723,8 @@ class ServiceManager(QtGui.QWidget):
Posts a remote edit message to a plugin to allow item to be edited.
"""
item, count = self.findServiceItem()
if self.serviceItems[item][u'service_item'].edit_enabled:
if self.serviceItems[item][u'service_item']\
.is_capable(ItemCapabilities.AllowsEdit):
self.remoteEditTriggered = True
Receiver.send_message(u'%s_edit' %
self.serviceItems[item][u'service_item'].name, u'L:%s' %
@ -728,18 +773,13 @@ class ServiceManager(QtGui.QWidget):
link = event.mimeData()
if link.hasText():
plugin = event.mimeData().text()
item = self.ServiceManagerList.itemAt(event.pos())
if plugin == u'ServiceManager':
startpos, startCount = self.findServiceItem()
item = self.ServiceManagerList.itemAt(event.pos())
if item is None:
endpos = len(self.serviceItems)
else:
parentitem = item.parent()
if parentitem is None:
endpos = item.data(0, QtCore.Qt.UserRole).toInt()[0]
else:
endpos = parentitem.data(0, QtCore.Qt.UserRole).toInt()[0]
endpos -= 1
endpos = self._getParentItemData(item) - 1
if endpos < startpos:
newpos = endpos
else:
@ -749,6 +789,10 @@ class ServiceManager(QtGui.QWidget):
self.serviceItems.insert(newpos, serviceItem)
self.repaintServiceList(endpos, startCount)
else:
if item == None:
self.droppos = len(self.serviceItems)
else:
self.droppos = self._getParentItemData(item)
Receiver.send_message(u'%s_add_service_item' % plugin)
def updateThemeList(self, theme_list):
@ -783,3 +827,10 @@ class ServiceManager(QtGui.QWidget):
item, count = self.findServiceItem()
self.serviceItems[item][u'service_item'].theme = theme
self.regenerateServiceItems()
def _getParentItemData(self, item):
parentitem = item.parent()
if parentitem is None:
return item.data(0, QtCore.Qt.UserRole).toInt()[0]
else:
return parentitem.data(0, QtCore.Qt.UserRole).toInt()[0]

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -24,9 +24,9 @@
###############################################################################
from PyQt4 import QtCore, QtGui
from serviceitemdialog import Ui_ServiceNoteEdit
from servicenotedialog import Ui_ServiceNoteEdit
class ServiceItemNoteForm(QtGui.QDialog, Ui_ServiceNoteEdit):
class ServiceNoteForm(QtGui.QDialog, Ui_ServiceNoteEdit):
"""
This is the form that is used to edit the verses of the song.
"""

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -59,4 +59,4 @@ class Ui_SettingsDialog(object):
QtCore.QMetaObject.connectSlotsByName(SettingsDialog)
def retranslateUi(self, SettingsDialog):
SettingsDialog.setWindowTitle(self.trUtf8('Settings'))
SettingsDialog.setWindowTitle(self.trUtf8('Settings'))

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -28,24 +28,23 @@ import logging
from PyQt4 import QtGui
from openlp.core.ui import GeneralTab, ThemesTab
from openlp.core.lib import Receiver
from settingsdialog import Ui_SettingsDialog
log = logging.getLogger(__name__)
class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
def __init__(self, screen_list, mainWindow, parent=None):
def __init__(self, screens, mainWindow, parent=None):
QtGui.QDialog.__init__(self, parent)
self.setupUi(self)
# General tab
self.GeneralTab = GeneralTab(screen_list)
self.GeneralTab = GeneralTab(screens)
self.addTab(u'General', self.GeneralTab)
# Themes tab
self.ThemesTab = ThemesTab(mainWindow)
self.addTab(u'Themes', self.ThemesTab)
def addTab(self, name, tab):
def addTab(self, name, tab):
log.info(u'Adding %s tab' % tab.tabTitle)
self.SettingsTabWidget.addTab(tab, tab.tabTitleVisible)
@ -65,7 +64,6 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
def accept(self):
for tab_index in range(0, self.SettingsTabWidget.count()):
self.SettingsTabWidget.widget(tab_index).save()
Receiver.send_message(u'config_updated')
return QtGui.QDialog.accept(self)
def postSetUp(self):

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -30,6 +30,17 @@ import os
from PyQt4 import QtCore, QtGui
from PyQt4.phonon import Phonon
from openlp.core.lib import ItemCapabilities
class HideMode(object):
"""
This is basically an enumeration class which specifies the mode of a Bible.
Mode refers to whether or not a Bible in OpenLP is a full Bible or needs to
be downloaded from the Internet on an as-needed basis.
"""
Blank = 1
Theme = 2
from openlp.core.lib import OpenLPToolbar, Receiver, str_to_bool, \
PluginConfig, resize_image
@ -85,7 +96,7 @@ class SlideController(QtGui.QWidget):
self.isLive = isLive
self.parent = parent
self.songsconfig = PluginConfig(u'Songs')
self.image_list = [
self.loop_list = [
u'Start Loop',
u'Stop Loop',
u'Loop Separator',
@ -94,6 +105,10 @@ class SlideController(QtGui.QWidget):
self.song_edit_list = [
u'Edit Song',
]
if isLive:
self.labelWidth = 20
else:
self.labelWidth = 0
self.timer_id = 0
self.songEdit = False
self.selectedRow = 0
@ -133,12 +148,14 @@ class SlideController(QtGui.QWidget):
self.ControllerLayout.setMargin(0)
# Controller list view
self.PreviewListWidget = SlideList(self)
self.PreviewListWidget.setColumnCount(1)
self.PreviewListWidget.setColumnCount(2)
self.PreviewListWidget.horizontalHeader().setVisible(False)
self.PreviewListWidget.verticalHeader().setVisible(False)
self.PreviewListWidget.setColumnWidth(1, self.Controller.width())
self.PreviewListWidget.setColumnWidth(1, self.labelWidth)
self.PreviewListWidget.setColumnWidth(1, self.Controller.width() - self.labelWidth)
self.PreviewListWidget.isLive = self.isLive
self.PreviewListWidget.setObjectName(u'PreviewListWidget')
self.PreviewListWidget.setSelectionBehavior(1)
self.PreviewListWidget.setEditTriggers(
QtGui.QAbstractItemView.NoEditTriggers)
self.PreviewListWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
@ -170,18 +187,24 @@ class SlideController(QtGui.QWidget):
if self.isLive:
self.Toolbar.addToolbarSeparator(u'Close Separator')
self.blankButton = self.Toolbar.addToolbarButton(
u'Blank Screen', u':/slides/slide_close.png',
u'Blank Screen', u':/slides/slide_blank.png',
self.trUtf8('Blank Screen'), self.onBlankDisplay, True)
self.themeButton = self.Toolbar.addToolbarButton(
u'Display Theme', u':/slides/slide_theme.png',
self.trUtf8('Theme Screen'), self.onThemeDisplay, True)
self.hideButton = self.Toolbar.addToolbarButton(
u'Hide screen', u':/slides/slide_desktop.png',
self.trUtf8('Hide Screen'), self.onHideDisplay, True)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'live_slide_blank'), self.blankScreen)
if not self.isLive:
self.Toolbar.addToolbarSeparator(u'Close Separator')
self.Toolbar.addToolbarButton(
u'Go Live', u':/system/system_live.png',
u'Go Live', u':/general/general_live.png',
self.trUtf8('Move to live'), self.onGoLive)
self.Toolbar.addToolbarSeparator(u'Close Separator')
self.Toolbar.addToolbarButton(
u'Edit Song', u':/services/service_edit.png',
u'Edit Song', u':/general/general_edit.png',
self.trUtf8('Edit and re-preview Song'), self.onEditSong)
if isLive:
self.Toolbar.addToolbarSeparator(u'Loop Separator')
@ -210,6 +233,12 @@ class SlideController(QtGui.QWidget):
self.Mediabar.addToolbarButton(
u'Media Stop', u':/slides/media_playback_stop.png',
self.trUtf8('Start playing media'), self.onMediaStop)
if not self.isLive:
self.seekSlider = Phonon.SeekSlider()
self.seekSlider.setGeometry(QtCore.QRect(90, 260, 221, 24))
self.seekSlider.setObjectName(u'seekSlider')
self.Mediabar.addToolbarWidget(
u'Seek Slider', self.seekSlider)
self.volumeSlider = Phonon.VolumeSlider()
self.volumeSlider.setGeometry(QtCore.QRect(90, 260, 221, 24))
self.volumeSlider.setObjectName(u'volumeSlider')
@ -276,7 +305,7 @@ class SlideController(QtGui.QWidget):
QtCore.SIGNAL(u'update_spin_delay'), self.receiveSpinDelay)
Receiver.send_message(u'request_spin_delay')
if isLive:
self.Toolbar.makeWidgetsInvisible(self.image_list)
self.Toolbar.makeWidgetsInvisible(self.loop_list)
else:
self.Toolbar.makeWidgetsInvisible(self.song_edit_list)
self.Mediabar.setVisible(False)
@ -299,6 +328,8 @@ class SlideController(QtGui.QWidget):
QtCore.SIGNAL(u'%s_change' % prefix), self.onSlideChange)
QtCore.QObject.connect(self.Splitter,
QtCore.SIGNAL(u'splitterMoved(int, int)'), self.trackSplitter)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_updated'), self.refreshServiceItem)
def widthChanged(self):
"""
@ -307,7 +338,8 @@ class SlideController(QtGui.QWidget):
"""
width = self.parent.ControlSplitter.sizes()[self.split]
height = width * self.parent.RenderManager.screen_ratio
self.PreviewListWidget.setColumnWidth(0, width)
self.PreviewListWidget.setColumnWidth(0, self.labelWidth)
self.PreviewListWidget.setColumnWidth(1, width - self.labelWidth)
#Sort out image hights (Songs , bibles excluded)
if self.serviceItem and not self.serviceItem.is_text():
for framenumber, frame in enumerate(self.serviceItem.get_frames()):
@ -348,20 +380,19 @@ class SlideController(QtGui.QWidget):
self.Toolbar.setVisible(True)
self.Mediabar.setVisible(False)
self.Toolbar.makeWidgetsInvisible([u'Song Menu'])
self.Toolbar.makeWidgetsInvisible(self.image_list)
self.Toolbar.makeWidgetsInvisible(self.loop_list)
if item.is_text():
self.Toolbar.makeWidgetsInvisible(self.image_list)
if item.is_song() and \
str_to_bool(self.songsconfig.get_config(u'show songbar', True)):
self.Toolbar.makeWidgetsInvisible(self.loop_list)
if str_to_bool(self.songsconfig.get_config(u'show songbar', True)) \
and len(self.slideList) > 0:
self.Toolbar.makeWidgetsVisible([u'Song Menu'])
elif item.is_image():
#Not sensible to allow loops with 1 frame
if len(item.get_frames()) > 1:
self.Toolbar.makeWidgetsVisible(self.image_list)
elif item.is_media():
if item.is_capable(ItemCapabilities.AllowsLoop) and \
len(item.get_frames()) > 1:
self.Toolbar.makeWidgetsVisible(self.loop_list)
if item.is_media():
self.Toolbar.setVisible(False)
self.Mediabar.setVisible(True)
self.volumeSlider.setAudioOutput(self.parent.mainDisplay.audio)
#self.volumeSlider.setAudioOutput(self.parent.mainDisplay.videoDisplay.audio)
def enablePreviewToolBar(self, item):
"""
@ -370,13 +401,24 @@ class SlideController(QtGui.QWidget):
self.Toolbar.setVisible(True)
self.Mediabar.setVisible(False)
self.Toolbar.makeWidgetsInvisible(self.song_edit_list)
if item.edit_enabled and item.fromPlugin:
if item.is_capable(ItemCapabilities.AllowsEdit) and item.from_plugin:
self.Toolbar.makeWidgetsVisible(self.song_edit_list)
elif item.is_media():
self.Toolbar.setVisible(False)
self.Mediabar.setVisible(True)
self.volumeSlider.setAudioOutput(self.audio)
def refreshServiceItem(self):
"""
Method to update the service item if the screen has changed
"""
log.debug(u'refreshServiceItem')
if self.serviceItem:
if self.serviceItem.is_text() or self.serviceItem.is_image():
item = self.serviceItem
item.render()
self.addServiceManagerItem(item, self.selectedRow)
def addServiceItem(self, item):
"""
Method to install the service item into the controller
@ -390,14 +432,14 @@ class SlideController(QtGui.QWidget):
if self.songEdit:
slideno = self.selectedRow
self.songEdit = False
self.addServiceManagerItem(item, slideno)
self._processItem(item, slideno)
def replaceServiceManagerItem(self, item):
"""
Replacement item following a remote edit
"""
if item.__eq__(self.serviceItem):
self.addServiceManagerItem(item, self.PreviewListWidget.currentRow())
self._processItem(item, self.PreviewListWidget.currentRow())
def addServiceManagerItem(self, item, slideno):
"""
@ -406,27 +448,32 @@ class SlideController(QtGui.QWidget):
Called by ServiceManager
"""
log.debug(u'addServiceManagerItem')
#If old item was a command tell it to stop
if self.serviceItem and self.serviceItem.is_command():
self.onMediaStop()
if item.is_media():
self.onMediaStart(item)
elif item.is_command():
if self.isLive:
blanked = self.blankButton.isChecked()
else:
blanked = False
Receiver.send_message(u'%s_start' % item.name.lower(), \
[item.title, item.service_item_path,
item.get_frame_title(), slideno, self.isLive, blanked])
self.displayServiceManagerItems(item, slideno)
#If service item is the same as the current on only change slide
if item.__eq__(self.serviceItem):
self.PreviewListWidget.selectRow(slideno)
self.onSlideSelected()
return
self._processItem(item, slideno)
def displayServiceManagerItems(self, serviceItem, slideno):
def _processItem(self, serviceItem, slideno):
"""
Loads a ServiceItem into the system from ServiceManager
Display the slide number passed
"""
log.debug(u'displayServiceManagerItems Start')
log.debug(u'processsManagerItem')
#If old item was a command tell it to stop
if self.serviceItem and self.serviceItem.is_command():
self.onMediaStop()
if serviceItem.is_media():
self.onMediaStart(serviceItem)
elif serviceItem.is_command():
if self.isLive:
blanked = self.blankButton.isChecked()
else:
blanked = False
Receiver.send_message(u'%s_start' % serviceItem.name.lower(), \
[serviceItem.title, serviceItem.get_frame_path(),
serviceItem.get_frame_title(), slideno, self.isLive, blanked])
self.slideList = {}
width = self.parent.ControlSplitter.sizes()[self.split]
#Set pointing cursor when we have somthing to point at
@ -435,12 +482,15 @@ class SlideController(QtGui.QWidget):
self.serviceItem = serviceItem
self.PreviewListWidget.clear()
self.PreviewListWidget.setRowCount(0)
self.PreviewListWidget.setColumnWidth(0, width)
self.PreviewListWidget.setColumnWidth(0, self.labelWidth)
self.PreviewListWidget.setColumnWidth(1, width - self.labelWidth)
if self.isLive:
self.SongMenu.menu().clear()
row = 0
for framenumber, frame in enumerate(self.serviceItem.get_frames()):
self.PreviewListWidget.setRowCount(
self.PreviewListWidget.rowCount() + 1)
rowitem = QtGui.QTableWidgetItem()
item = QtGui.QTableWidgetItem()
slide_height = 0
#It is a based Text Render
@ -450,18 +500,21 @@ class SlideController(QtGui.QWidget):
bits = frame[u'verseTag'].split(u':')
tag = None
#If verse handle verse number else tag only
if bits[0] == self.trUtf8('Verse'):
tag = u'%s%s' % (bits[0][0], bits[1][0:] )
row = bits[1][0:]
if bits[0] == self.trUtf8('Verse') or \
bits[0] == self.trUtf8('Chorus'):
tag = u'%s\n%s' % (bits[0][0], bits[1][0:] )
tag1 = u'%s%s' % (bits[0][0], bits[1][0:] )
row = tag
else:
tag = bits[0]
tag1 = tag
row = bits[0][0:1]
try:
test = self.slideList[tag]
except:
self.slideList[tag] = framenumber
self.SongMenu.menu().addAction(self.trUtf8(u'%s'%tag),
if tag1 not in self.slideList:
self.slideList[tag1] = framenumber
self.SongMenu.menu().addAction(self.trUtf8(u'%s'%tag1),
self.onSongBarHandler)
else:
row += 1
item.setText(frame[u'text'])
else:
label = QtGui.QLabel()
@ -471,15 +524,20 @@ class SlideController(QtGui.QWidget):
self.parent.RenderManager.height)
label.setScaledContents(True)
label.setPixmap(QtGui.QPixmap.fromImage(pixmap))
self.PreviewListWidget.setCellWidget(framenumber, 0, label)
self.PreviewListWidget.setCellWidget(framenumber, 1, label)
slide_height = width * self.parent.RenderManager.screen_ratio
self.PreviewListWidget.setItem(framenumber, 0, item)
row += 1
rowitem.setText(unicode(row))
rowitem.setTextAlignment(QtCore.Qt.AlignVCenter)
self.PreviewListWidget.setItem(framenumber, 0, rowitem)
self.PreviewListWidget.setItem(framenumber, 1, item)
if slide_height != 0:
self.PreviewListWidget.setRowHeight(framenumber, slide_height)
if self.serviceItem.is_text():
self.PreviewListWidget.resizeRowsToContents()
self.PreviewListWidget.setColumnWidth(
0, self.PreviewListWidget.viewport().size().width())
self.PreviewListWidget.setColumnWidth(0, self.labelWidth)
self.PreviewListWidget.setColumnWidth(1,
self.PreviewListWidget.viewport().size().width() - self.labelWidth )
if slideno > self.PreviewListWidget.rowCount():
self.PreviewListWidget.selectRow(self.PreviewListWidget.rowCount())
else:
@ -490,7 +548,6 @@ class SlideController(QtGui.QWidget):
log.log(15, u'Display Rendering took %4s' % (time.time() - before))
if self.isLive:
self.serviceItem.request_audit()
log.debug(u'displayServiceManagerItems End')
#Screen event methods
def onSlideSelectedFirst(self):
@ -511,13 +568,35 @@ class SlideController(QtGui.QWidget):
"""
Handle the blank screen button
"""
log.debug(u'onBlankDisplay %d' % force)
if force:
self.blankButton.setChecked(True)
self.blankScreen(self.blankButton.isChecked())
self.blankScreen(HideMode.Blank, self.blankButton.isChecked())
self.parent.generalConfig.set_config(u'screen blank',
self.blankButton.isChecked())
def blankScreen(self, blanked=False):
def onThemeDisplay(self, force=False):
"""
Handle the Theme screen button
"""
log.debug(u'onThemeDisplay %d' % force)
if force:
self.themeButton.setChecked(True)
self.blankScreen(HideMode.Theme, self.themeButton.isChecked())
def onHideDisplay(self, force=False):
"""
Handle the Hide screen button
"""
log.debug(u'onHideDisplay %d' % force)
if force:
self.hideButton.setChecked(True)
if self.hideButton.isChecked():
self.parent.mainDisplay.hideDisplay()
else:
self.parent.mainDisplay.showDisplay()
def blankScreen(self, blankType, blanked=False):
"""
Blank the display screen.
"""
@ -527,8 +606,10 @@ class SlideController(QtGui.QWidget):
Receiver.send_message(u'%s_blank'% self.serviceItem.name.lower())
else:
Receiver.send_message(u'%s_unblank'% self.serviceItem.name.lower())
else:
self.parent.mainDisplay.blankDisplay(blankType, blanked)
else:
self.parent.mainDisplay.blankDisplay(blanked)
self.parent.mainDisplay.blankDisplay(blankType, blanked)
def onSlideSelected(self):
"""
@ -554,7 +635,7 @@ class SlideController(QtGui.QWidget):
self.SlidePreview.setPixmap(QtGui.QPixmap.fromImage(frame[u'main']))
log.log(15, u'Slide Rendering took %4s' % (time.time() - before))
if self.isLive:
self.parent.mainDisplay.frameView(frame, True)
self.parent.displayManager.mainDisplay.frameView(frame, True)
self.selectedRow = row
def onSlideChange(self, row):
@ -572,7 +653,7 @@ class SlideController(QtGui.QWidget):
QtCore.QTimer.singleShot(2.5, self.grabMainDisplay)
else:
label = self.PreviewListWidget.cellWidget(
self.PreviewListWidget.currentRow(), 0)
self.PreviewListWidget.currentRow(), 1)
self.SlidePreview.setPixmap(label.pixmap())
def grabMainDisplay(self):
@ -641,7 +722,8 @@ class SlideController(QtGui.QWidget):
self.serviceItem.name.lower(), self.isLive)
self.updatePreview()
else:
self.PreviewListWidget.selectRow(self.PreviewListWidget.rowCount() - 1)
self.PreviewListWidget.selectRow(
self.PreviewListWidget.rowCount() - 1)
self.onSlideSelected()
def onStartLoop(self):
@ -682,13 +764,15 @@ class SlideController(QtGui.QWidget):
def onMediaStart(self, item):
if self.isLive:
Receiver.send_message(u'%s_start' % item.name.lower(), \
[item.title, item.service_item_path,
[item.title, item.get_frame_path(),
item.get_frame_title(), self.isLive, self.blankButton.isChecked()])
else:
self.mediaObject.stop()
self.mediaObject.clearQueue()
file = os.path.join(item.service_item_path, item.get_frame_title())
file = os.path.join(item.get_frame_path(), item.get_frame_title())
self.mediaObject.setCurrentSource(Phonon.MediaSource(file))
self.seekSlider.setMediaObject(self.mediaObject)
self.seekSlider.show()
self.onMediaPlay()
def onMediaPause(self):

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -67,4 +67,4 @@ class SplashScreen(object):
self.splash_screen.repaint()
def finish(self, widget):
self.splash_screen.finish(widget)
self.splash_screen.finish(widget)

View File

@ -1,153 +0,0 @@
"""
OpenLP - Open Source Lyrics Projection
Copyright (c) 2008 Raoul Snyman
Portions copyright (c) 2008 Martin Thompson, Tim Bentley
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
"""
import sys
import os
import os.path
import logging
from PyQt4 import QtGui
from openlp.core.ui import ServiceManager
from openlp.plugins.images.lib import ImageServiceItem
mypath = os.path.split(os.path.abspath(__file__))[0]
sys.path.insert(0, (os.path.join(mypath, '..', '..', '..', '..')))
logging.basicConfig(filename='test_service_manager.log', level=logging.INFO,
filemode='w')
# # from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66062
# def whoami(depth=1):
# return sys._getframe(depth).f_code.co_name
global app
global log
log = logging.getLogger(u'TestServiceManager')
class TestServiceManager_base:
def __init__(self):
pass
def setup_class(self):
log.info( "class setup" + unicode(self))
try:
if app is None:
app = QtGui.QApplication([])
except UnboundLocalError:
app = QtGui.QApplication([])
def teardown_class(self):
pass
def setup_method(self, method):
log.info(u'Setup method:' + unicode(method))
self.expected_answer = "Don't know yet"
self.answer = None
self.s = ServiceManager(None)
log.info(u'--------------- Setup Done -------------')
def teardown_method(self, method):
self.s = None
def select_row(self, row):
# now select the line we just added
# first get the index
i = QModelIndex(self.s.service_data.index(0,0))
# make a selection of it
self.sm = QItemSelectionModel(self.s.service_data)
self.sm.select(i, QItemSelectionModel.ClearAndSelect)
log.info(unicode(self.sm.selectedIndexes()))
self.s.TreeView.setSelectionModel(self.sm)
log.info(u'Selected indexes = ' + unicode(
self.s.TreeView.selectedIndexes()))
def test_easy(self):
log.info(u'test_easy')
item = ImageServiceItem(None)
item.add(u'test.gif')
self.s.addServiceItem(item)
answer = self.s.service_as_text()
log.info(u'Answer = ' + unicode(answer))
lines = answer.split(u'\n')
log.info(u'lines = ' + unicode(lines))
assert lines[0].startswith(u'# <openlp.plugins.images.imageserviceitem.ImageServiceItem object')
assert lines[1] == "test.gif"
log.info(u'done')
def test_2items_as_separate_items(self):
# If nothing is selected when item is added, a new base service item
# is added
log.info(u'test_2items_as_separate_items')
item = ImageServiceItem(None)
item.add(u'test.gif')
self.s.addServiceItem(item)
item = ImageServiceItem(None)
item.add(u'test2.gif')
item.add(u'test3.gif')
self.s.addServiceItem(item)
answer = self.s.service_as_text()
log.info(u'Answer = ' + unicode(answer))
lines = answer.split(u'\n')
log.info(u'lines = ' + unicode(lines))
assert lines[0].startswith(u'# <openlp.plugins.images.imageserviceitem.ImageServiceItem object')
assert lines[1] == "test.gif"
assert lines[2].startswith(u'# <openlp.plugins.images.imageserviceitem.ImageServiceItem object')
assert lines[3] == "test2.gif"
assert lines[4] == "test3.gif"
log.info(u'done')
def test_2items_merged(self):
# If the first object is selected when item is added it should be
# extended
log.info(u'test_2items_merged')
item = ImageServiceItem(None)
item.add(u'test.gif')
self.s.addServiceItem(item)
self.select_row(0)
log.info(u'Selected indexes = ' + unicode(
self.s.TreeView.selectedIndexes()))
item = ImageServiceItem(None)
item.add(u'test2.gif')
item.add(u'test3.gif')
self.s.addServiceItem(item)
answer = self.s.service_as_text()
log.info(u'Answer = ' + unicode(answer))
lines = answer.split(u'\n')
log.info(u'lines = ' + unicode(lines))
assert lines[0].startswith(u'# <openlp.plugins.images.imageserviceitem.ImageServiceItem object')
assert lines[1] == "test.gif"
assert lines[2] == "test2.gif"
assert lines[3] == "test3.gif"
log.info(u'done')
# more tests to do:
# add different types of service item
# move up, down
# move to top, bottom
# new and save as
# deleting items
if __name__ == "__main__":
t=TestServiceManager_base()
t.setup_class()
t.setup_method(None)
t.test_easy()
t.teardown_method(None)
print "Pass"
log.info(u'Pass')

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -59,14 +59,14 @@ class ThemeManager(QtGui.QWidget):
self.trUtf8('Edit Theme'), u':/themes/theme_edit.png',
self.trUtf8('Edit a theme'), self.onEditTheme)
self.Toolbar.addToolbarButton(
self.trUtf8('Delete Theme'), u':/themes/theme_delete.png',
self.trUtf8('Delete Theme'), u':/general/general_delete.png',
self.trUtf8('Delete a theme'), self.onDeleteTheme)
self.Toolbar.addSeparator()
self.Toolbar.addToolbarButton(
self.trUtf8('Import Theme'), u':/themes/theme_import.png',
self.trUtf8('Import Theme'), u':/general/general_import.png',
self.trUtf8('Import a theme'), self.onImportTheme)
self.Toolbar.addToolbarButton(
self.trUtf8('Export Theme'), u':/themes/theme_export.png',
self.trUtf8('Export Theme'), u':/general/general_export.png',
self.trUtf8('Export a theme'), self.onExportTheme)
self.ThemeWidget = QtGui.QWidgetAction(self.Toolbar)
self.Layout.addWidget(self.Toolbar)
@ -82,17 +82,17 @@ class ThemeManager(QtGui.QWidget):
contextMenuSeparator(self.ThemeListWidget))
self.ThemeListWidget.addAction(
contextMenuAction(self.ThemeListWidget,
u':/themes/theme_delete.png',
u':/general/general_delete.png',
self.trUtf8('Delete theme'),
self.onDeleteTheme))
self.ThemeListWidget.addAction(
contextMenuAction(self.ThemeListWidget,
u':/themes/theme_export.png',
u':/general/general_export.png',
self.trUtf8('Make Global'),
self.changeGlobalFromScreen))
self.ThemeListWidget.addAction(
contextMenuAction(self.ThemeListWidget,
u':/themes/theme_export.png',
u':/general/general_export.png',
self.trUtf8('Export theme'),
self.onExportTheme))
self.ThemeListWidget.addAction(
@ -177,20 +177,20 @@ class ThemeManager(QtGui.QWidget):
if theme != unicode(item.data(QtCore.Qt.UserRole).toString()):
QtGui.QMessageBox.critical(
self, self.trUtf8('Error'),
self.trUtf8('You are unable to delete the default theme!'),
self.trUtf8('You are unable to delete the default theme.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
else:
for plugin in self.parent.plugin_manager.plugins:
if not plugin.can_delete_theme(theme):
QtGui.QMessageBox.critical(
self, self.trUtf8('Error'),
self.trUtf8('theme %s is use in %s plugin' % (theme, plugin.name)),
self.trUtf8('Theme %s is use in %s plugin' % (theme, plugin.name)),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
return
if unicode(self.parent.ServiceManagerContents.ThemeComboBox.currentText()) == theme:
QtGui.QMessageBox.critical(
self, self.trUtf8('Error'),
self.trUtf8('theme %s is use Service Manager' % theme),
self.trUtf8('Theme %s is use by Service Manager' % theme),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
return
self.themelist.remove(theme)
@ -216,7 +216,7 @@ class ThemeManager(QtGui.QWidget):
item = self.ThemeListWidget.currentItem()
if item is None:
QtGui.QMessageBox.critical(self, self.trUtf8('Error'),
self.trUtf8('You have not selected a theme!'),
self.trUtf8('You have not selected a theme.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
return
theme = unicode(item.data(QtCore.Qt.UserRole).toString())
@ -359,7 +359,7 @@ class ThemeManager(QtGui.QWidget):
except:
QtGui.QMessageBox.critical(
self, self.trUtf8('Error'),
self.trUtf8('File is not a valid theme!'),
self.trUtf8('File is not a valid theme.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
log.exception(u'Importing theme from zip file failed %s' % filename)
finally:

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -159,9 +159,10 @@ class ThemesTab(SettingsTab):
image = self.parent.ThemeManagerContents.getPreviewImage(
self.global_theme)
preview = QtGui.QPixmap(unicode(image))
display = preview.scaled(300, 255, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
self.DefaultListView.setPixmap(display)
if not preview.isNull():
preview = preview.scaled(300, 255, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
self.DefaultListView.setPixmap(preview)
def updateThemeList(self, theme_list):
"""
@ -184,6 +185,7 @@ class ThemesTab(SettingsTab):
image = self.parent.ThemeManagerContents.getPreviewImage(
self.global_theme)
preview = QtGui.QPixmap(unicode(image))
display = preview.scaled(300, 255, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
self.DefaultListView.setPixmap(display)
if not preview.isNull():
preview = preview.scaled(300, 255, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
self.DefaultListView.setPixmap(preview)

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -29,6 +29,10 @@ import logging
import urllib2
from datetime import datetime
from PyQt4 import QtCore
import openlp
log = logging.getLogger(__name__)
class AppLocation(object):
@ -39,15 +43,22 @@ class AppLocation(object):
ConfigDir = 2
DataDir = 3
PluginsDir = 4
VersionDir = 5
@staticmethod
def get_directory(dir_type):
def get_directory(dir_type=1):
"""
Return the appropriate directory according to the directory type.
``dir_type``
The directory type you want, for instance the data directory.
"""
if dir_type == AppLocation.AppDir:
return os.path.abspath(os.path.split(sys.argv[0])[0])
return os.path.abspath(os.path.split(sys.argv[0])[0])
elif dir_type == AppLocation.ConfigDir:
if os.name == u'nt':
if sys.platform == u'win32':
path = os.path.join(os.getenv(u'APPDATA'), u'openlp')
elif os.name == u'mac':
elif sys.platform == u'darwin':
path = os.path.join(os.getenv(u'HOME'), u'Library',
u'Application Support', u'openlp')
else:
@ -58,9 +69,9 @@ class AppLocation(object):
path = os.path.join(os.getenv(u'HOME'), u'.openlp')
return path
elif dir_type == AppLocation.DataDir:
if os.name == u'nt':
if sys.platform == u'win32':
path = os.path.join(os.getenv(u'APPDATA'), u'openlp', u'data')
elif os.name == u'mac':
elif sys.platform == u'darwin':
path = os.path.join(os.getenv(u'HOME'), u'Library',
u'Application Support', u'openlp', u'Data')
else:
@ -71,33 +82,74 @@ class AppLocation(object):
path = os.path.join(os.getenv(u'HOME'), u'.openlp', u'data')
return path
elif dir_type == AppLocation.PluginsDir:
plugin_path = None
app_path = os.path.abspath(os.path.split(sys.argv[0])[0])
if hasattr(sys, u'frozen') and sys.frozen == 1:
return os.path.join(app_path, u'plugins')
plugin_path = os.path.join(app_path, u'plugins')
else:
return os.path.join(app_path, u'openlp', u'plugins')
plugin_path = os.path.join(
os.path.split(openlp.__file__)[0], u'plugins')
return plugin_path
elif dir_type == AppLocation.VersionDir:
if hasattr(sys, u'frozen') and sys.frozen == 1:
plugin_path = os.path.abspath(os.path.split(sys.argv[0])[0])
else:
plugin_path = os.path.split(openlp.__file__)[0]
return plugin_path
def check_latest_version(config, current_version):
version_string = current_version
"""
Check the latest version of OpenLP against the version file on the OpenLP
site.
``config``
The OpenLP config object.
``current_version``
The current version of OpenLP.
"""
version_string = current_version[u'full']
#set to prod in the distribution confif file.
last_test = config.get_config(u'last version test', datetime.now().date())
this_test = unicode(datetime.now().date())
config.set_config(u'last version test', this_test)
if last_test != this_test:
version_string = u''
req = urllib2.Request(u'http://www.openlp.org/files/version.txt')
req.add_header(u'User-Agent', u'OpenLP/%s' % current_version)
if current_version[u'build']:
req = urllib2.Request(u'http://www.openlp.org/files/dev_version.txt')
else:
req = urllib2.Request(u'http://www.openlp.org/files/version.txt')
req.add_header(u'User-Agent', u'OpenLP/%s' % current_version[u'full'])
try:
handle = urllib2.urlopen(req, None)
html = handle.read()
version_string = unicode(html).rstrip()
version_string = unicode(urllib2.urlopen(req, None).read()).strip()
except IOError, e:
if hasattr(e, u'reason'):
log.exception(u'Reason for failure: %s', e.reason)
return version_string
def string_to_unicode(string):
"""
Converts a QString to a Python unicode object.
"""
if isinstance(string, QtCore.QString):
string = unicode(string.toUtf8(), u'utf8')
return string
def variant_to_unicode(variant):
"""
Converts a QVariant to a Python unicode object.
``variant``
The QVariant instance to convert to unicode.
"""
if isinstance(variant, QtCore.QVariant):
string = variant.toString()
if not isinstance(string, unicode):
string = string_to_unicode(string)
return string
from registry import Registry
from confighelper import ConfigHelper
__all__ = [u'Registry', u'ConfigHelper', u'AppLocations', u'check_latest_version']
__all__ = [u'Registry', u'ConfigHelper', u'AppLocation', u'check_latest_version']

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -41,15 +41,17 @@ class Registry(object):
"""
Check if a value exists.
"""
return self.config.has_option(section, key)
return self.config.has_option(section.encode('utf-8'),
key.encode('utf-8'))
def get_value(self, section, key, default=None):
"""
Get a single value from the registry.
"""
try:
if self.config.get(section, key):
return self.config.get(section, key)
if self.config.get(section.encode('utf-8'), key.encode('utf-8')):
return self.config.get(section.encode('utf-8'),
key.encode('utf-8')).decode('utf-8')
else:
return default
except:
@ -60,7 +62,8 @@ class Registry(object):
Set a single value in the registry.
"""
try :
self.config.set(section, key, unicode(value))
self.config.set(section.encode('utf-8'), key.encode('utf-8'),
unicode(value).encode('utf-8'))
return self._save()
except:
return False
@ -70,7 +73,8 @@ class Registry(object):
Delete a single value from the registry.
"""
try:
self.config.remove_option(section, key)
self.config.remove_option(section.encode('utf-8'),
key.encode('utf-8'))
return self._save()
except:
return False
@ -79,14 +83,14 @@ class Registry(object):
"""
Check if a section exists.
"""
return self.config.has_section(section)
return self.config.has_section(section.encode('utf-8'))
def create_section(self, section):
"""
Create a new section in the registry.
"""
try:
self.config.add_section(section)
self.config.add_section(section.encode('utf-8'))
return self._save()
except:
return False
@ -96,7 +100,7 @@ class Registry(object):
Delete a section (including all values).
"""
try:
self.config.remove_section(section)
self.config.remove_section(section.encode('utf-8'))
return self._save()
except:
return False
@ -127,4 +131,4 @@ class Registry(object):
return False
finally:
if file_handle:
file_handle.close()
file_handle.close()

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -21,4 +21,4 @@
# 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 #
###############################################################################
###############################################################################

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -23,10 +23,203 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
import os
import sys
import sqlite3
from sqlalchemy import *
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker, mapper
from openlp.core.lib import PluginConfig
from openlp.plugins.bibles.lib.models import *
class BaseModel(object):
"""
BaseModel provides a base object with a set of generic functions
"""
@classmethod
def populate(cls, **kwargs):
"""
Creates an instance of a class and populates it, returning the instance
"""
me = cls()
keys = kwargs.keys()
for key in keys:
me.__setattr__(key, kwargs[key])
return me
class TBibleMeta(BaseModel):
"""
Bible Meta Data
"""
pass
class TTestament(BaseModel):
"""
Bible Testaments
"""
pass
class TBook(BaseModel):
"""
Song model
"""
pass
class TVerse(BaseModel):
"""
Topic model
"""
pass
temp_meta_table = Table(u'metadata_temp', metadata,
Column(u'key', types.Unicode(255), primary_key=True),
Column(u'value', types.Unicode(255)),
)
temp_testament_table = Table(u'testament_temp', metadata,
Column(u'id', types.Integer, primary_key=True),
Column(u'name', types.Unicode(30)),
)
temp_book_table = Table(u'book_temp', metadata,
Column(u'id', types.Integer, primary_key=True),
Column(u'testament_id', types.Integer),
Column(u'name', types.Unicode(30)),
Column(u'abbreviation', types.Unicode(5)),
)
temp_verse_table = Table(u'verse_temp', metadata,
Column(u'id', types.Integer, primary_key=True),
Column(u'book_id', types.Integer),
Column(u'chapter', types.Integer),
Column(u'verse', types.Integer),
Column(u'text', types.UnicodeText),
)
mapper(TBibleMeta, temp_meta_table)
mapper(TTestament, temp_testament_table)
mapper(TBook, temp_book_table)
mapper(TVerse, temp_verse_table)
def init_models(url):
engine = create_engine(url)
metadata.bind = engine
session = scoped_session(sessionmaker(autoflush=False,
autocommit=False, bind=engine))
return session
class MigrateBibles():
def __init__(self, display):
self.display = display
self.config = PluginConfig(u'Bibles')
self.data_path = self.config.get_data_path()
self.database_files = self.config.get_files(u'sqlite')
print self.database_files
def progress(self, text):
print text
self.display.output(text)
def process(self):
self.display.output(u'Bible process started')
self.display.output(u'Bible process finished')
self.progress(u'Bibles processing started')
for f in self.database_files:
self.v_1_9_0(f)
self.progress(u'Bibles processing finished')
def v_1_9_0(self, database):
self.progress(u'Migration 1.9.0 Started for ' + database)
self._v1_9_0_old(database)
self._v1_9_0_new(database)
self._v1_9_0_cleanup(database)
self.progress(u'Migration 1.9.0 Finished for ' + database)
def _v1_9_0_old(self, database):
self.progress(u'Rename Tables ' + database)
conn = sqlite3.connect(os.path.join(self.data_path, database))
conn.execute(u'alter table book rename to book_temp;')
conn.commit()
conn.execute(u'alter table testament rename to testament_temp;')
conn.commit()
conn.execute(u'alter table verse rename to verse_temp;')
conn.commit()
conn.execute(u'alter table metadata rename to metadata_temp;')
conn.commit()
def _v1_9_0_new(self, database):
self.progress(u'Create new Tables ' + database)
self.db_url = u'sqlite:///' + self.data_path + u'/' + database
print self.db_url
self.session = init_models(self.db_url)
metadata.create_all(checkfirst=True)
self.progress(u'Create testament table')
results = self.session.query(TTestament).order_by(TTestament.id).all()
for testament_temp in results:
testament = Testament()
testament.id = testament_temp.id
testament.name = testament_temp.name
try:
self.session.add(testament)
self.session.commit()
except:
self.session.rollback()
print u'Error thrown = ', sys.exc_info()[1]
self.progress(u'Create book table')
results = self.session.query(TBook).order_by(TBook.id).all()
for book_temp in results:
book = Book()
book.id = book_temp.id
book.testament_id = book_temp.testament_id
book.name = book_temp.name
book.abbreviation = book_temp.abbreviation
try:
self.session.add(book)
self.session.commit()
except:
self.session.rollback()
print u'Error thrown = ', sys.exc_info()[1]
self.progress(u'Create verse table')
results = self.session.query(TVerse).order_by(TVerse.id).all()
for verse_temp in results:
verse = Verse()
verse.id = verse_temp.id
verse.book_id = verse_temp.book_id
verse.chapter = verse_temp.chapter
verse.verse = verse_temp.verse
verse.text = verse_temp.text
try:
self.session.add(verse)
except:
self.session.rollback()
print u'Error thrown = ', sys.exc_info()[1]
try:
self.session.commit()
except:
self.session.rollback()
print u'Error thrown = ', sys.exc_info()[1]
self.progress(u'Create metadata table')
results = self.session.query(TBibleMeta).order_by(TBibleMeta.key).all()
for biblemeta_temp in results:
biblemeta = BibleMeta()
biblemeta.key = biblemeta_temp.key
biblemeta.value = biblemeta_temp.value
try:
self.session.add(biblemeta)
self.session.commit()
except:
self.session.rollback()
print u'Error thrown = ', sys.exc_info()[1]
def _v1_9_0_cleanup(self, database):
self.progress(u'Update Internal Data ' + database)
conn = sqlite3.connect(os.path.join(self.data_path, database))
conn.commit()
conn.execute(u'drop table book_temp;')
conn.commit()
conn.execute(u'drop table testament_temp;')
conn.commit()
conn.execute(u'drop table verse_temp;')
conn.commit()
conn.execute(u'drop table metadata_temp;')
conn.commit()
conn.execute(u'vacuum;')
conn.commit()

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -46,4 +46,4 @@ class MigrateFiles():
self.display.sub_output(u'images created')
ConfigHelper.get_config(u'presentations', u'data path')
self.display.sub_output(u'presentations created')
self.display.output(u'Initial Setup finished')
self.display.output(u'Initial Setup finished')

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -198,4 +198,4 @@ class MigrateSongs():
conn.execute(u'drop table songauthors_temp;')
conn.commit()
conn.execute(u'drop table settings;')
conn.commit()
conn.commit()

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -21,4 +21,4 @@
# 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 #
###############################################################################
###############################################################################

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -21,4 +21,4 @@
# 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 #
###############################################################################
###############################################################################

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -27,9 +27,9 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, build_icon, PluginStatus
from openlp.core.lib import Plugin, build_icon, PluginStatus, Receiver
from openlp.plugins.alerts.lib import AlertsManager, DBManager
from openlp.plugins.alerts.forms import AlertsTab, AlertForm, AlertEditForm
from openlp.plugins.alerts.forms import AlertsTab, AlertForm
log = logging.getLogger(__name__)
@ -43,7 +43,6 @@ class alertsPlugin(Plugin):
self.alertsmanager = AlertsManager(self)
self.manager = DBManager(self.config)
self.alertForm = AlertForm(self.manager, self)
self.alertEditForm = AlertEditForm(self.manager, self)
self.status = PluginStatus.Active
def get_settings_tab(self):
@ -89,10 +88,7 @@ class alertsPlugin(Plugin):
def onAlertsTrigger(self):
self.alertForm.loadList()
self.alertForm.exec_()
def onAlertsEdit(self):
self.alertEditForm.loadList()
self.alertEditForm.exec_()
Receiver.send_message(u'text_onTop')
def about(self):
about_text = self.trUtf8('<b>Alerts Plugin</b><br>This plugin '

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -25,4 +25,3 @@
from alertstab import AlertsTab
from alertform import AlertForm
from alerteditform import AlertEditForm

View File

@ -1,71 +1,134 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'alertform.ui'
# Form implementation generated from reading ui file 'alertdialog.ui'
#
# Created: Sat Feb 13 08:19:51 2010
# by: PyQt4 UI code generator 4.6.2
# Created: Sat Apr 17 08:07:40 2010
# by: PyQt4 UI code generator 4.7
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
class Ui_AlertDialog(object):
def setupUi(self, AlertForm):
AlertForm.setObjectName(u'AlertDialog')
AlertForm.resize(430, 320)
def setupUi(self, AlertDialog):
AlertDialog.setObjectName("AlertDialog")
AlertDialog.resize(567, 440)
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(u':/icon/openlp.org-icon-32.bmp'), QtGui.QIcon.Normal, QtGui.QIcon.Off)
AlertForm.setWindowIcon(icon)
self.AlertFormLayout = QtGui.QVBoxLayout(AlertForm)
icon.addPixmap(QtGui.QPixmap(":/icon/openlp.org-icon-32.bmp"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
AlertDialog.setWindowIcon(icon)
self.AlertFormLayout = QtGui.QVBoxLayout(AlertDialog)
self.AlertFormLayout.setSpacing(8)
self.AlertFormLayout.setMargin(8)
self.AlertFormLayout.setObjectName(u'AlertFormLayout')
self.AlertEntryWidget = QtGui.QWidget(AlertForm)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.AlertEntryWidget.sizePolicy().hasHeightForWidth())
self.AlertEntryWidget.setSizePolicy(sizePolicy)
self.AlertEntryWidget.setObjectName(u'AlertEntryWidget')
self.verticalLayout_2 = QtGui.QVBoxLayout(self.AlertEntryWidget)
self.verticalLayout_2.setObjectName(u'verticalLayout_2')
self.verticalLayout = QtGui.QVBoxLayout()
self.verticalLayout.setObjectName(u'verticalLayout')
self.AlertEntryLabel = QtGui.QLabel(self.AlertEntryWidget)
self.AlertFormLayout.setObjectName("AlertFormLayout")
self.AlertTextLayout = QtGui.QFormLayout()
self.AlertTextLayout.setContentsMargins(0, 0, -1, -1)
self.AlertTextLayout.setSpacing(8)
self.AlertTextLayout.setObjectName("AlertTextLayout")
self.AlertEntryLabel = QtGui.QLabel(AlertDialog)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.AlertEntryLabel.sizePolicy().hasHeightForWidth())
self.AlertEntryLabel.setSizePolicy(sizePolicy)
self.AlertEntryLabel.setObjectName(u'AlertEntryLabel')
self.verticalLayout.addWidget(self.AlertEntryLabel)
self.AlertEntryEditItem = QtGui.QLineEdit(self.AlertEntryWidget)
self.AlertEntryEditItem.setObjectName(u'AlertEntryEditItem')
self.verticalLayout.addWidget(self.AlertEntryEditItem)
self.AlertListWidget = QtGui.QListWidget(self.AlertEntryWidget)
self.AlertEntryLabel.setObjectName("AlertEntryLabel")
self.AlertTextLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.AlertEntryLabel)
self.AlertParameter = QtGui.QLabel(AlertDialog)
self.AlertParameter.setObjectName("AlertParameter")
self.AlertTextLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.AlertParameter)
self.ParameterEdit = QtGui.QLineEdit(AlertDialog)
self.ParameterEdit.setObjectName("ParameterEdit")
self.AlertTextLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.ParameterEdit)
self.AlertTextEdit = QtGui.QLineEdit(AlertDialog)
self.AlertTextEdit.setObjectName("AlertTextEdit")
self.AlertTextLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.AlertTextEdit)
self.AlertFormLayout.addLayout(self.AlertTextLayout)
self.ManagementLayout = QtGui.QHBoxLayout()
self.ManagementLayout.setSpacing(8)
self.ManagementLayout.setContentsMargins(-1, -1, -1, 0)
self.ManagementLayout.setObjectName("ManagementLayout")
self.AlertListWidget = QtGui.QListWidget(AlertDialog)
self.AlertListWidget.setAlternatingRowColors(True)
self.AlertListWidget.setObjectName(u'AlertListWidget')
self.verticalLayout.addWidget(self.AlertListWidget)
self.verticalLayout_2.addLayout(self.verticalLayout)
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName(u'horizontalLayout')
spacerItem = QtGui.QSpacerItem(181, 38, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem)
self.DisplayButton = QtGui.QPushButton(self.AlertEntryWidget)
self.DisplayButton.setObjectName(u'DisplayButton')
self.horizontalLayout.addWidget(self.DisplayButton)
self.CancelButton = QtGui.QPushButton(self.AlertEntryWidget)
self.CancelButton.setObjectName(u'CancelButton')
self.horizontalLayout.addWidget(self.CancelButton)
self.verticalLayout_2.addLayout(self.horizontalLayout)
self.AlertFormLayout.addWidget(self.AlertEntryWidget)
self.AlertListWidget.setObjectName("AlertListWidget")
self.ManagementLayout.addWidget(self.AlertListWidget)
self.ManageButtonLayout = QtGui.QVBoxLayout()
self.ManageButtonLayout.setSpacing(8)
self.ManageButtonLayout.setObjectName("ManageButtonLayout")
self.NewButton = QtGui.QPushButton(AlertDialog)
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap(":/general/general_new.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.NewButton.setIcon(icon1)
self.NewButton.setObjectName("NewButton")
self.ManageButtonLayout.addWidget(self.NewButton)
self.SaveButton = QtGui.QPushButton(AlertDialog)
self.SaveButton.setEnabled(False)
icon2 = QtGui.QIcon()
icon2.addPixmap(QtGui.QPixmap(":/general/general_save.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.SaveButton.setIcon(icon2)
self.SaveButton.setObjectName("SaveButton")
self.ManageButtonLayout.addWidget(self.SaveButton)
self.EditButton = QtGui.QPushButton(AlertDialog)
icon3 = QtGui.QIcon()
icon3.addPixmap(QtGui.QPixmap(":/general/general_edit.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.EditButton.setIcon(icon3)
self.EditButton.setObjectName("EditButton")
self.ManageButtonLayout.addWidget(self.EditButton)
self.DeleteButton = QtGui.QPushButton(AlertDialog)
icon4 = QtGui.QIcon()
icon4.addPixmap(QtGui.QPixmap(":/general/general_delete.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.DeleteButton.setIcon(icon4)
self.DeleteButton.setObjectName("DeleteButton")
self.ManageButtonLayout.addWidget(self.DeleteButton)
spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.ManageButtonLayout.addItem(spacerItem)
self.ManagementLayout.addLayout(self.ManageButtonLayout)
self.AlertFormLayout.addLayout(self.ManagementLayout)
self.AlertButtonLayout = QtGui.QHBoxLayout()
self.AlertButtonLayout.setSpacing(8)
self.AlertButtonLayout.setObjectName("AlertButtonLayout")
spacerItem1 = QtGui.QSpacerItem(181, 0, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.AlertButtonLayout.addItem(spacerItem1)
self.DisplayButton = QtGui.QPushButton(AlertDialog)
icon5 = QtGui.QIcon()
icon5.addPixmap(QtGui.QPixmap(":/general/general_live.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.DisplayButton.setIcon(icon5)
self.DisplayButton.setObjectName("DisplayButton")
self.AlertButtonLayout.addWidget(self.DisplayButton)
self.DisplayCloseButton = QtGui.QPushButton(AlertDialog)
self.DisplayCloseButton.setIcon(icon5)
self.DisplayCloseButton.setObjectName("DisplayCloseButton")
self.AlertButtonLayout.addWidget(self.DisplayCloseButton)
self.CloseButton = QtGui.QPushButton(AlertDialog)
icon6 = QtGui.QIcon()
icon6.addPixmap(QtGui.QPixmap(":/system/system_close.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.CloseButton.setIcon(icon6)
self.CloseButton.setObjectName("CloseButton")
self.AlertButtonLayout.addWidget(self.CloseButton)
self.AlertFormLayout.addLayout(self.AlertButtonLayout)
self.AlertEntryLabel.setBuddy(self.AlertTextEdit)
self.AlertParameter.setBuddy(self.ParameterEdit)
self.retranslateUi(AlertForm)
QtCore.QObject.connect(self.CancelButton, QtCore.SIGNAL(u'clicked()'), self.close)
QtCore.QMetaObject.connectSlotsByName(AlertForm)
self.retranslateUi(AlertDialog)
QtCore.QObject.connect(self.CloseButton, QtCore.SIGNAL("clicked()"), AlertDialog.close)
QtCore.QMetaObject.connectSlotsByName(AlertDialog)
AlertDialog.setTabOrder(self.AlertTextEdit, self.ParameterEdit)
AlertDialog.setTabOrder(self.ParameterEdit, self.AlertListWidget)
AlertDialog.setTabOrder(self.AlertListWidget, self.NewButton)
AlertDialog.setTabOrder(self.NewButton, self.SaveButton)
AlertDialog.setTabOrder(self.SaveButton, self.EditButton)
AlertDialog.setTabOrder(self.EditButton, self.DeleteButton)
AlertDialog.setTabOrder(self.DeleteButton, self.DisplayButton)
AlertDialog.setTabOrder(self.DisplayButton, self.DisplayCloseButton)
AlertDialog.setTabOrder(self.DisplayCloseButton, self.CloseButton)
def retranslateUi(self, AlertDialog):
AlertDialog.setWindowTitle(QtGui.QApplication.translate("AlertDialog", "Alert Message", None, QtGui.QApplication.UnicodeUTF8))
self.AlertEntryLabel.setText(QtGui.QApplication.translate("AlertDialog", "Alert &text:", None, QtGui.QApplication.UnicodeUTF8))
self.AlertParameter.setText(QtGui.QApplication.translate("AlertDialog", "&Parameter(s):", None, QtGui.QApplication.UnicodeUTF8))
self.NewButton.setText(QtGui.QApplication.translate("AlertDialog", "&New", None, QtGui.QApplication.UnicodeUTF8))
self.SaveButton.setText(QtGui.QApplication.translate("AlertDialog", "&Save", None, QtGui.QApplication.UnicodeUTF8))
self.EditButton.setText(QtGui.QApplication.translate("AlertDialog", "&Edit", None, QtGui.QApplication.UnicodeUTF8))
self.DeleteButton.setText(QtGui.QApplication.translate("AlertDialog", "&Delete", None, QtGui.QApplication.UnicodeUTF8))
self.DisplayButton.setText(QtGui.QApplication.translate("AlertDialog", "Displ&ay", None, QtGui.QApplication.UnicodeUTF8))
self.DisplayCloseButton.setText(QtGui.QApplication.translate("AlertDialog", "Display && Cl&ose", None, QtGui.QApplication.UnicodeUTF8))
self.CloseButton.setText(QtGui.QApplication.translate("AlertDialog", "&Close", None, QtGui.QApplication.UnicodeUTF8))
def retranslateUi(self, AlertForm):
AlertForm.setWindowTitle(self.trUtf8('Alert Message'))
self.AlertEntryLabel.setText(self.trUtf8('Alert Text:'))
self.DisplayButton.setText(self.trUtf8('Display'))
self.CancelButton.setText(self.trUtf8('Cancel'))

View File

@ -1,67 +0,0 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'alerteditdialog.ui'
#
# Created: Sun Feb 14 16:45:10 2010
# by: PyQt4 UI code generator 4.6.2
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
class Ui_AlertEditDialog(object):
def setupUi(self, AlertEditDialog):
AlertEditDialog.setObjectName(u'AlertEditDialog')
AlertEditDialog.resize(400, 300)
self.buttonBox = QtGui.QDialogButtonBox(AlertEditDialog)
self.buttonBox.setGeometry(QtCore.QRect(220, 270, 173, 27))
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel)
self.buttonBox.setObjectName(u'buttonBox')
self.layoutWidget = QtGui.QWidget(AlertEditDialog)
self.layoutWidget.setGeometry(QtCore.QRect(20, 10, 361, 251))
self.layoutWidget.setObjectName(u'layoutWidget')
self.verticalLayout_2 = QtGui.QVBoxLayout(self.layoutWidget)
self.verticalLayout_2.setObjectName(u'verticalLayout_2')
self.horizontalLayout_2 = QtGui.QHBoxLayout()
self.horizontalLayout_2.setObjectName(u'horizontalLayout_2')
self.AlertLineEdit = QtGui.QLineEdit(self.layoutWidget)
self.AlertLineEdit.setObjectName(u'AlertLineEdit')
self.horizontalLayout_2.addWidget(self.AlertLineEdit)
self.verticalLayout_2.addLayout(self.horizontalLayout_2)
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName(u'horizontalLayout')
self.AlertListWidget = QtGui.QListWidget(self.layoutWidget)
self.AlertListWidget.setAlternatingRowColors(True)
self.AlertListWidget.setObjectName(u'AlertListWidget')
self.horizontalLayout.addWidget(self.AlertListWidget)
self.verticalLayout = QtGui.QVBoxLayout()
self.verticalLayout.setObjectName(u'verticalLayout')
self.SaveButton = QtGui.QPushButton(self.layoutWidget)
self.SaveButton.setObjectName(u'SaveButton')
self.verticalLayout.addWidget(self.SaveButton)
self.ClearButton = QtGui.QPushButton(self.layoutWidget)
self.ClearButton.setObjectName(u'ClearButton')
self.verticalLayout.addWidget(self.ClearButton)
self.AddButton = QtGui.QPushButton(self.layoutWidget)
self.AddButton.setObjectName(u'AddButton')
self.verticalLayout.addWidget(self.AddButton)
self.EditButton = QtGui.QPushButton(self.layoutWidget)
self.EditButton.setObjectName(u'EditButton')
self.verticalLayout.addWidget(self.EditButton)
self.DeleteButton = QtGui.QPushButton(self.layoutWidget)
self.DeleteButton.setObjectName(u'DeleteButton')
self.verticalLayout.addWidget(self.DeleteButton)
self.horizontalLayout.addLayout(self.verticalLayout)
self.verticalLayout_2.addLayout(self.horizontalLayout)
self.retranslateUi(AlertEditDialog)
QtCore.QMetaObject.connectSlotsByName(AlertEditDialog)
def retranslateUi(self, AlertEditDialog):
AlertEditDialog.setWindowTitle(self.trUtf8('Maintain Alerts'))
self.SaveButton.setText(self.trUtf8('Save'))
self.ClearButton.setText(self.trUtf8('Clear'))
self.AddButton.setText(self.trUtf8('Add'))
self.EditButton.setText(self.trUtf8('Edit'))
self.DeleteButton.setText(self.trUtf8('Delete'))

View File

@ -1,166 +0,0 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 openlp.plugins.alerts.lib.models import AlertItem
from alerteditdialog import Ui_AlertEditDialog
class AlertEditForm(QtGui.QDialog, Ui_AlertEditDialog):
"""
Class documentation goes here.
"""
def __init__(self, manager, parent):
"""
Constructor
"""
self.manager = manager
self.parent = parent
QtGui.QDialog.__init__(self, None)
self.setupUi(self)
QtCore.QObject.connect(self.DeleteButton,
QtCore.SIGNAL(u'clicked()'),
self.onDeleteClick)
QtCore.QObject.connect(self.ClearButton,
QtCore.SIGNAL(u'clicked()'),
self.onClearClick)
QtCore.QObject.connect(self.EditButton,
QtCore.SIGNAL(u'clicked()'),
self.onEditClick)
QtCore.QObject.connect(self.AddButton,
QtCore.SIGNAL(u'clicked()'),
self.onAddClick)
QtCore.QObject.connect(self.SaveButton,
QtCore.SIGNAL(u'clicked()'),
self.onSaveClick)
QtCore.QObject.connect(self.buttonBox,
QtCore.SIGNAL(u'rejected()'), self.close)
QtCore.QObject.connect(self.AlertLineEdit,
QtCore.SIGNAL(u'textChanged(const QString&)'),
self.onTextChanged)
QtCore.QObject.connect(self.AlertListWidget,
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
self.onItemSelected)
QtCore.QObject.connect(self.AlertListWidget,
QtCore.SIGNAL(u'clicked(QModelIndex)'),
self.onItemSelected)
def loadList(self):
self.AlertListWidget.clear()
alerts = self.manager.get_all_alerts()
for alert in alerts:
item_name = QtGui.QListWidgetItem(alert.text)
item_name.setData(
QtCore.Qt.UserRole, QtCore.QVariant(alert.id))
self.AlertListWidget.addItem(item_name)
self.AddButton.setEnabled(True)
self.ClearButton.setEnabled(False)
self.SaveButton.setEnabled(False)
self.EditButton.setEnabled(False)
self.DeleteButton.setEnabled(False)
def onItemSelected(self):
if self.AlertLineEdit.text():
QtGui.QMessageBox.information(self,
self.trUtf8('Item selected to Edit'),
self.trUtf8('Please Save or Clear seletced item'))
else:
self.EditButton.setEnabled(True)
self.DeleteButton.setEnabled(True)
def onDeleteClick(self):
item = self.AlertListWidget.currentItem()
if item:
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
self.parent.manager.delete_alert(item_id)
row = self.AlertListWidget.row(item)
self.AlertListWidget.takeItem(row)
self.AddButton.setEnabled(True)
self.SaveButton.setEnabled(False)
self.DeleteButton.setEnabled(False)
self.EditButton.setEnabled(False)
def onEditClick(self):
item = self.AlertListWidget.currentItem()
if item:
self.item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
self.AlertLineEdit.setText(unicode(item.text()))
self.AddButton.setEnabled(True)
self.ClearButton.setEnabled(True)
self.SaveButton.setEnabled(True)
self.DeleteButton.setEnabled(True)
self.EditButton.setEnabled(False)
def onClearClick(self):
self.AlertLineEdit.setText(u'')
self.AddButton.setEnabled(False)
self.ClearButton.setEnabled(True)
self.SaveButton.setEnabled(False)
self.DeleteButton.setEnabled(False)
self.EditButton.setEnabled(False)
def onAddClick(self):
if len(self.AlertLineEdit.text()) == 0:
QtGui.QMessageBox.information(self,
self.trUtf8('Item selected to Add'),
self.trUtf8('Missing data'))
else:
alert = AlertItem()
alert.text = unicode(self.AlertLineEdit.text())
self.manager.save_alert(alert)
self.onClearClick()
self.loadList()
def onSaveClick(self):
alert = self.manager.get_alert(self.item_id)
alert.text = unicode(self.AlertLineEdit.text())
self.manager.save_alert(alert)
self.onClearClick()
self.loadList()
def onTextChanged(self):
self.AddButton.setEnabled(True)
def onDoubleClick(self):
"""
List item has been double clicked to display it
"""
items = self.AlertListWidget.selectedIndexes()
for item in items:
bitem = self.AlertListWidget.item(item.row())
self.triggerAlert(bitem.text())
def onSingleClick(self):
"""
List item has been single clicked to add it to
the edit field so it can be changed.
"""
items = self.AlertListWidget.selectedIndexes()
for item in items:
bitem = self.AlertListWidget.item(item.row())
self.AlertEntryEditItem.setText(bitem.text())
def triggerAlert(self, text):
self.parent.alertsmanager.displayAlert(text)

View File

@ -6,8 +6,8 @@
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
@ -45,9 +45,24 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
QtCore.QObject.connect(self.DisplayButton,
QtCore.SIGNAL(u'clicked()'),
self.onDisplayClicked)
QtCore.QObject.connect(self.AlertEntryEditItem,
QtCore.QObject.connect(self.DisplayCloseButton,
QtCore.SIGNAL(u'clicked()'),
self.onDisplayCloseClicked)
QtCore.QObject.connect(self.AlertTextEdit,
QtCore.SIGNAL(u'textChanged(const QString&)'),
self.onTextChanged)
QtCore.QObject.connect(self.NewButton,
QtCore.SIGNAL(u'clicked()'),
self.onNewClick)
QtCore.QObject.connect(self.DeleteButton,
QtCore.SIGNAL(u'clicked()'),
self.onDeleteClick)
QtCore.QObject.connect(self.EditButton,
QtCore.SIGNAL(u'clicked()'),
self.onEditClick)
QtCore.QObject.connect(self.SaveButton,
QtCore.SIGNAL(u'clicked()'),
self.onSaveClick)
QtCore.QObject.connect(self.AlertListWidget,
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
self.onDoubleClick)
@ -60,19 +75,64 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
alerts = self.manager.get_all_alerts()
for alert in alerts:
item_name = QtGui.QListWidgetItem(alert.text)
item_name.setData(
QtCore.Qt.UserRole, QtCore.QVariant(alert.id))
self.AlertListWidget.addItem(item_name)
self.SaveButton.setEnabled(False)
self.EditButton.setEnabled(False)
self.DeleteButton.setEnabled(False)
def onDisplayClicked(self):
self.triggerAlert(unicode(self.AlertEntryEditItem.text()))
if self.parent.alertsTab.save_history and self.history_required:
if self.triggerAlert(unicode(self.AlertTextEdit.text())):
self.history_required = False
self.loadList()
def onDisplayCloseClicked(self):
if self.triggerAlert(unicode(self.AlertTextEdit.text())):
self.close()
def onDeleteClick(self):
item = self.AlertListWidget.currentItem()
if item:
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
self.parent.manager.delete_alert(item_id)
row = self.AlertListWidget.row(item)
self.AlertListWidget.takeItem(row)
self.AlertTextEdit.setText(u'')
self.SaveButton.setEnabled(False)
self.DeleteButton.setEnabled(False)
self.EditButton.setEnabled(False)
def onEditClick(self):
item = self.AlertListWidget.currentItem()
if item:
self.item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
self.AlertTextEdit.setText(unicode(item.text()))
self.SaveButton.setEnabled(True)
self.DeleteButton.setEnabled(True)
self.EditButton.setEnabled(False)
def onNewClick(self):
if len(self.AlertTextEdit.text()) == 0:
QtGui.QMessageBox.information(self,
self.trUtf8('Item selected to Add'),
self.trUtf8('Missing data'))
else:
alert = AlertItem()
alert.text = unicode(self.AlertEntryEditItem.text())
alert.text = unicode(self.AlertTextEdit.text())
self.manager.save_alert(alert)
self.history_required = False
self.onClearClick()
self.loadList()
def onSaveClick(self):
alert = self.manager.get_alert(self.item_id)
alert.text = unicode(self.AlertTextEdit.text())
self.manager.save_alert(alert)
self.onClearClick()
self.loadList()
def onTextChanged(self):
#Data has changed by editing it so potential storage
#Data has changed by editing it so potential storage required
self.history_required = True
def onDoubleClick(self):
@ -93,8 +153,17 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
items = self.AlertListWidget.selectedIndexes()
for item in items:
bitem = self.AlertListWidget.item(item.row())
self.AlertEntryEditItem.setText(bitem.text())
self.AlertTextEdit.setText(bitem.text())
self.history_required = False
self.EditButton.setEnabled(True)
self.DeleteButton.setEnabled(True)
def triggerAlert(self, text):
self.parent.alertsmanager.displayAlert(text)
if text:
self.parent.alertsmanager.displayAlert(text)
if self.parent.alertsTab.save_history and self.history_required:
alert = AlertItem()
alert.text = unicode(self.AlertTextEdit.text())
self.manager.save_alert(alert)
return True
return False

Some files were not shown because too many files have changed in this diff Show More