This commit is contained in:
Andreas Preikschat 2011-03-22 07:06:35 +01:00
commit 0aa748ca3d
52 changed files with 8465 additions and 7598 deletions

View File

@ -4,6 +4,7 @@ recursive-include openlp *.csv
recursive-include openlp *.html
recursive-include openlp *.js
recursive-include openlp *.css
recursive-include openlp *.png
recursive-include documentation *
recursive-include resources *
recursive-include scripts *

View File

@ -173,7 +173,9 @@ class OpenLP(QtGui.QApplication):
has_run_wizard = QtCore.QSettings().value(
u'general/has run wizard', QtCore.QVariant(False)).toBool()
if not has_run_wizard:
FirstTimeForm(screens).exec_()
if FirstTimeForm(screens).exec_() == QtGui.QDialog.Accepted:
QtCore.QSettings().setValue(u'general/has run wizard',
QtCore.QVariant(True))
if os.name == u'nt':
self.setStyleSheet(application_stylesheet)
show_splash = QtCore.QSettings().value(

View File

@ -183,8 +183,9 @@ class ServiceItem(object):
else:
log.error(u'Invalid value renderer :%s' % self.service_item_type)
self.title = clean_tags(self.title)
# The footer should never be None, but to be compatible with older
# release of OpenLP, we have to correct this to avoid tracebacks.
# The footer should never be None, but to be compatible with a few
# nightly builds between 1.9.4 and 1.9.5, we have to correct this to
# avoid tracebacks.
if self.raw_footer is None:
self.raw_footer = []
self.foot_text = \
@ -447,4 +448,5 @@ class ServiceItem(object):
elif not start and end:
return end
else:
return u'%s : %s' % (start, end)
return u'%s : %s' % (start, end)

View File

@ -33,7 +33,8 @@ from ConfigParser import SafeConfigParser
from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate, PluginStatus, Receiver, build_icon
from openlp.core.lib import translate, PluginStatus, Receiver, build_icon, \
check_directory_exists
from openlp.core.utils import get_web_page, AppLocation
from firsttimewizard import Ui_FirstTimeWizard, FirstTimePage
@ -49,6 +50,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
def __init__(self, screens, parent=None):
QtGui.QWizard.__init__(self, parent)
self.setupUi(self)
self.screens = screens
# check to see if we have web access
self.web = u'http://openlp.org/files/frw/'
self.config = SafeConfigParser()
@ -56,12 +58,13 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
if self.webAccess:
files = self.webAccess.read()
self.config.readfp(io.BytesIO(files))
self.displayComboBox.addItems(screens.get_screen_list())
self.updateScreenListCombo()
self.downloading = unicode(translate('OpenLP.FirstTimeWizard',
'Downloading %s...'))
QtCore.QObject.connect(self,
QtCore.SIGNAL(u'currentIdChanged(int)'),
self.onCurrentIdChanged)
QtCore.SIGNAL(u'currentIdChanged(int)'), self.onCurrentIdChanged)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_screen_changed'), self.updateScreenListCombo)
def exec_(self, edit=False):
"""
@ -75,6 +78,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
Set up display at start of theme edit.
"""
self.restart()
check_directory_exists(os.path.join(gettempdir(), u'openlp'))
# Sort out internet access for downloads
if self.webAccess:
songs = self.config.get(u'songs', u'languages')
@ -111,8 +115,6 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
self.biblesTreeWidget.expandAll()
themes = self.config.get(u'themes', u'files')
themes = themes.split(u',')
if not os.path.exists(os.path.join(gettempdir(), u'openlp')):
os.makedirs(os.path.join(gettempdir(), u'openlp'))
for theme in themes:
title = self.config.get(u'theme_%s' % theme, u'title')
filename = self.config.get(u'theme_%s' % theme, u'filename')
@ -160,6 +162,25 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
self._performWizard()
self._postWizard()
def updateScreenListCombo(self):
"""
The user changed screen resolution or enabled/disabled more screens, so
we need to update the combo box.
"""
self.displayComboBox.clear()
self.displayComboBox.addItems(self.screens.get_screen_list())
self.displayComboBox.setCurrentIndex(self.displayComboBox.count() - 1)
def _getFileSize(self, url):
site = urllib.urlopen(url)
meta = site.info()
return int(meta.getheaders("Content-Length")[0])
def _downloadProgress(self, count, block_size, total_size):
increment = (count * block_size) - self.previous_size
self._incrementProgressBar(None, increment)
self.previous_size = count * block_size
def _incrementProgressBar(self, status_text, increment=1):
"""
Update the wizard progress page.
@ -184,19 +205,27 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
max_progress = 2
# Loop through the songs list and increase for each selected item
for i in xrange(self.songsListWidget.count()):
if self.songsListWidget.item(i).checkState() == QtCore.Qt.Checked:
max_progress += 1
item = self.songsListWidget.item(i)
if item.checkState() == QtCore.Qt.Checked:
filename = item.data(QtCore.Qt.UserRole).toString()
size = self._getFileSize(u'%s%s' % (self.web, filename))
max_progress += size
# Loop through the Bibles list and increase for each selected item
iterator = QtGui.QTreeWidgetItemIterator(self.biblesTreeWidget)
while iterator.value():
item = iterator.value()
if item.parent() and item.checkState(0) == QtCore.Qt.Checked:
max_progress += 1
filename = item.data(0, QtCore.Qt.UserRole).toString()
size = self._getFileSize(u'%s%s' % (self.web, filename))
max_progress += size
iterator += 1
# Loop through the themes list and increase for each selected item
for i in xrange(self.themesListWidget.count()):
if self.themesListWidget.item(i).checkState() == QtCore.Qt.Checked:
max_progress += 1
item = self.themesListWidget.item(i)
if item.checkState() == QtCore.Qt.Checked:
filename = item.data(QtCore.Qt.UserRole).toString()
size = self._getFileSize(u'%s%s' % (self.web, filename))
max_progress += size
self.finishButton.setVisible(False)
self.progressBar.setValue(0)
self.progressBar.setMinimum(0)
@ -241,27 +270,33 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
item = self.songsListWidget.item(i)
if item.checkState() == QtCore.Qt.Checked:
filename = item.data(QtCore.Qt.UserRole).toString()
self._incrementProgressBar(self.downloading % filename)
self._incrementProgressBar(self.downloading % filename, 0)
self.previous_size = 0
destination = os.path.join(songs_destination, unicode(filename))
urllib.urlretrieve(u'%s%s' % (self.web, filename), destination)
urllib.urlretrieve(u'%s%s' % (self.web, filename), destination,
self._downloadProgress)
# Download Bibles
bibles_iterator = QtGui.QTreeWidgetItemIterator(self.biblesTreeWidget)
while bibles_iterator.value():
item = bibles_iterator.value()
if item.parent() and item.checkState(0) == QtCore.Qt.Checked:
bible = unicode(item.data(0, QtCore.Qt.UserRole).toString())
self._incrementProgressBar(self.downloading % bible)
self._incrementProgressBar(self.downloading % bible, 0)
self.previous_size = 0
urllib.urlretrieve(u'%s%s' % (self.web, bible),
os.path.join(bibles_destination, bible))
os.path.join(bibles_destination, bible),
self._downloadProgress)
bibles_iterator += 1
# Download themes
for i in xrange(self.themesListWidget.count()):
item = self.themesListWidget.item(i)
if item.checkState() == QtCore.Qt.Checked:
theme = unicode(item.data(QtCore.Qt.UserRole).toString())
self._incrementProgressBar(self.downloading % theme)
self._incrementProgressBar(self.downloading % theme, 0)
self.previous_size = 0
urllib.urlretrieve(u'%s%s' % (self.web, theme),
os.path.join(themes_destination, theme))
os.path.join(themes_destination, theme),
self._downloadProgress)
# Set Default Display
if self.displayComboBox.currentIndex() != -1:
QtCore.QSettings().setValue(u'General/monitor',
@ -270,8 +305,6 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
if self.themeComboBox.currentIndex() != -1:
QtCore.QSettings().setValue(u'themes/global theme',
QtCore.QVariant(self.themeComboBox.currentText()))
QtCore.QSettings().setValue(u'general/has run wizard',
QtCore.QVariant(True))
def _setPluginStatus(self, field, tag):
status = PluginStatus.Active if field.checkState() \

View File

@ -158,8 +158,6 @@ class Ui_FirstTimeWizard(object):
self.displayComboBox = QtGui.QComboBox(self.defaultsPage)
self.displayComboBox.setEditable(False)
self.displayComboBox.setInsertPolicy(QtGui.QComboBox.NoInsert)
self.displayComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToContents)
self.displayComboBox.setObjectName(u'displayComboBox')
self.defaultsLayout.addRow(self.displayLabel, self.displayComboBox)
self.themeLabel = QtGui.QLabel(self.defaultsPage)

View File

@ -32,27 +32,6 @@ from openlp.core.lib.ui import UiStrings
log = logging.getLogger(__name__)
class ValidEdit(QtGui.QLineEdit):
"""
Only allow numeric characters to be edited
"""
def __init__(self, parent):
"""
Set up Override and Validator
"""
QtGui.QLineEdit.__init__(self, parent)
self.setValidator(QtGui.QIntValidator(0, 9999, self))
def validText(self):
"""
Only return Integers. Space is 0
"""
if self.text().isEmpty():
return QtCore.QString(u'0')
else:
return self.text()
class GeneralTab(SettingsTab):
"""
GeneralTab is the general settings tab in the settings dialog.
@ -164,30 +143,6 @@ class GeneralTab(SettingsTab):
self.displayGroupBox.setObjectName(u'displayGroupBox')
self.displayLayout = QtGui.QGridLayout(self.displayGroupBox)
self.displayLayout.setObjectName(u'displayLayout')
self.currentXLabel = QtGui.QLabel(self.displayGroupBox)
self.currentXLabel.setObjectName(u'currentXLabel')
self.displayLayout.addWidget(self.currentXLabel, 0, 0)
self.currentXValueLabel = QtGui.QLabel(self.displayGroupBox)
self.currentXValueLabel.setObjectName(u'currentXValueLabel')
self.displayLayout.addWidget(self.currentXValueLabel, 1, 0)
self.currentYLabel = QtGui.QLabel(self.displayGroupBox)
self.currentYLabel.setObjectName(u'currentYLabel')
self.displayLayout.addWidget(self.currentYLabel, 0, 1)
self.currentYValueLabel = QtGui.QLabel(self.displayGroupBox)
self.currentYValueLabel.setObjectName(u'currentYValueLabel')
self.displayLayout.addWidget(self.currentYValueLabel, 1, 1)
self.currentWidthLabel = QtGui.QLabel(self.displayGroupBox)
self.currentWidthLabel.setObjectName(u'currentWidthLabel')
self.displayLayout.addWidget(self.currentWidthLabel, 0, 2)
self.currentWidthValueLabel = QtGui.QLabel(self.displayGroupBox)
self.currentWidthValueLabel.setObjectName(u'currentWidthValueLabel')
self.displayLayout.addWidget(self.currentWidthValueLabel, 1, 2)
self.currentHeightLabel = QtGui.QLabel(self.displayGroupBox)
self.currentHeightLabel.setObjectName(u'currentHeightLabel')
self.displayLayout.addWidget(self.currentHeightLabel, 0, 3)
self.currentHeightValueLabel = QtGui.QLabel(self.displayGroupBox)
self.currentHeightValueLabel.setObjectName(u'Height')
self.displayLayout.addWidget(self.currentHeightValueLabel, 1, 3)
self.overrideCheckBox = QtGui.QCheckBox(self.displayGroupBox)
self.overrideCheckBox.setObjectName(u'overrideCheckBox')
self.displayLayout.addWidget(self.overrideCheckBox, 2, 0, 1, 4)
@ -196,26 +151,30 @@ class GeneralTab(SettingsTab):
self.customXLabel = QtGui.QLabel(self.displayGroupBox)
self.customXLabel.setObjectName(u'customXLabel')
self.displayLayout.addWidget(self.customXLabel, 3, 0)
self.customXValueEdit = ValidEdit(self.displayGroupBox)
self.customXValueEdit = QtGui.QSpinBox(self.displayGroupBox)
self.customXValueEdit.setObjectName(u'customXValueEdit')
self.customXValueEdit.setMaximum(9999)
self.displayLayout.addWidget(self.customXValueEdit, 4, 0)
self.customYLabel = QtGui.QLabel(self.displayGroupBox)
self.customYLabel.setObjectName(u'customYLabel')
self.displayLayout.addWidget(self.customYLabel, 3, 1)
self.customYValueEdit = ValidEdit(self.displayGroupBox)
self.customYValueEdit = QtGui.QSpinBox(self.displayGroupBox)
self.customYValueEdit.setObjectName(u'customYValueEdit')
self.customYValueEdit.setMaximum(9999)
self.displayLayout.addWidget(self.customYValueEdit, 4, 1)
self.customWidthLabel = QtGui.QLabel(self.displayGroupBox)
self.customWidthLabel.setObjectName(u'customWidthLabel')
self.displayLayout.addWidget(self.customWidthLabel, 3, 2)
self.customWidthValueEdit = ValidEdit(self.displayGroupBox)
self.customWidthValueEdit = QtGui.QSpinBox(self.displayGroupBox)
self.customWidthValueEdit.setObjectName(u'customWidthValueEdit')
self.customWidthValueEdit.setMaximum(9999)
self.displayLayout.addWidget(self.customWidthValueEdit, 4, 2)
self.customHeightLabel = QtGui.QLabel(self.displayGroupBox)
self.customHeightLabel.setObjectName(u'customHeightLabel')
self.displayLayout.addWidget(self.customHeightLabel, 3, 3)
self.customHeightValueEdit = ValidEdit(self.displayGroupBox)
self.customHeightValueEdit = QtGui.QSpinBox(self.displayGroupBox)
self.customHeightValueEdit.setObjectName(u'customHeightValueEdit')
self.customHeightValueEdit.setMaximum(9999)
self.displayLayout.addWidget(self.customHeightValueEdit, 4, 3)
self.rightLayout.addWidget(self.displayGroupBox)
self.rightLayout.addStretch()
@ -223,17 +182,13 @@ class GeneralTab(SettingsTab):
QtCore.QObject.connect(self.overrideCheckBox,
QtCore.SIGNAL(u'toggled(bool)'), self.onOverrideCheckBoxToggled)
QtCore.QObject.connect(self.customHeightValueEdit,
QtCore.SIGNAL(u'textEdited(const QString&)'),
self.onDisplayPositionChanged)
QtCore.SIGNAL(u'valueChanged(int)'), self.onDisplayPositionChanged)
QtCore.QObject.connect(self.customWidthValueEdit,
QtCore.SIGNAL(u'textEdited(const QString&)'),
self.onDisplayPositionChanged)
QtCore.SIGNAL(u'valueChanged(int)'), self.onDisplayPositionChanged)
QtCore.QObject.connect(self.customYValueEdit,
QtCore.SIGNAL(u'textEdited(const QString&)'),
self.onDisplayPositionChanged)
QtCore.SIGNAL(u'valueChanged(int)'), self.onDisplayPositionChanged)
QtCore.QObject.connect(self.customXValueEdit,
QtCore.SIGNAL(u'textEdited(const QString&)'),
self.onDisplayPositionChanged)
QtCore.SIGNAL(u'valueChanged(int)'), self.onDisplayPositionChanged)
# Reload the tab, as the screen resolution/count may have changed.
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_screen_changed'), self.load)
@ -273,8 +228,7 @@ class GeneralTab(SettingsTab):
'Automatically preview next item in service'))
self.timeoutLabel.setText(translate('OpenLP.GeneralTab',
'Slide loop delay:'))
self.timeoutSpinBox.setSuffix(
translate('OpenLP.GeneralTab', ' sec'))
self.timeoutSpinBox.setSuffix(translate('OpenLP.GeneralTab', ' sec'))
self.ccliGroupBox.setTitle(
translate('OpenLP.GeneralTab', 'CCLI Details'))
self.numberLabel.setText(UiStrings.CCLINumberLabel)
@ -285,22 +239,11 @@ class GeneralTab(SettingsTab):
# Moved from display tab
self.displayGroupBox.setTitle(
translate('OpenLP.GeneralTab', 'Display Position'))
self.currentXLabel.setText(translate('OpenLP.GeneralTab', 'X'))
self.currentXValueLabel.setText(u'0')
self.currentYLabel.setText(translate('OpenLP.GeneralTab', 'Y'))
self.currentYValueLabel.setText(u'0')
self.currentHeightLabel.setText(
translate('OpenLP.GeneralTab', 'Height'))
self.currentHeightValueLabel.setText(u'0')
self.currentWidthLabel.setText(
translate('OpenLP.GeneralTab', 'Width'))
self.currentWidthValueLabel.setText(u'0')
self.overrideCheckBox.setText(translate('OpenLP.GeneralTab',
'Override display position'))
self.customXLabel.setText(translate('OpenLP.GeneralTab', 'X'))
self.customYLabel.setText(translate('OpenLP.GeneralTab', 'Y'))
self.customHeightLabel.setText(
translate('OpenLP.GeneralTab', 'Height'))
self.customHeightLabel.setText(translate('OpenLP.GeneralTab', 'Height'))
self.customWidthLabel.setText(translate('OpenLP.GeneralTab', 'Width'))
def load(self):
@ -310,8 +253,7 @@ class GeneralTab(SettingsTab):
settings = QtCore.QSettings()
settings.beginGroup(self.settingsSection)
self.monitorComboBox.clear()
for screen in self.screens.get_screen_list():
self.monitorComboBox.addItem(screen)
self.monitorComboBox.addItems(self.screens.get_screen_list())
self.numberEdit.setText(unicode(settings.value(
u'ccli number', QtCore.QVariant(u'')).toString()))
self.usernameEdit.setText(unicode(settings.value(
@ -334,26 +276,16 @@ class GeneralTab(SettingsTab):
QtCore.QVariant(False)).toBool())
self.timeoutSpinBox.setValue(settings.value(u'loop delay',
QtCore.QVariant(5)).toInt()[0])
self.currentXValueLabel.setText(
unicode(self.screens.current[u'size'].x()))
self.currentYValueLabel.setText(
unicode(self.screens.current[u'size'].y()))
self.currentHeightValueLabel.setText(
unicode(self.screens.current[u'size'].height()))
self.currentWidthValueLabel.setText(
unicode(self.screens.current[u'size'].width()))
self.overrideCheckBox.setChecked(settings.value(u'override position',
QtCore.QVariant(False)).toBool())
self.customXValueEdit.setText(settings.value(u'x position',
QtCore.QVariant(self.screens.current[u'size'].x())).toString())
self.customYValueEdit.setText(settings.value(u'y position',
QtCore.QVariant(self.screens.current[u'size'].y())).toString())
self.customHeightValueEdit.setText(
settings.value(u'height', QtCore.QVariant(
self.screens.current[u'size'].height())).toString())
self.customWidthValueEdit.setText(
settings.value(u'width', QtCore.QVariant(
self.screens.current[u'size'].width())).toString())
self.customXValueEdit.setValue(settings.value(u'x position',
QtCore.QVariant(self.screens.current[u'size'].x())).toInt()[0])
self.customYValueEdit.setValue(settings.value(u'y position',
QtCore.QVariant(self.screens.current[u'size'].y())).toInt()[0])
self.customHeightValueEdit.setValue(settings.value(u'height',
QtCore.QVariant(self.screens.current[u'size'].height())).toInt()[0])
self.customWidthValueEdit.setValue(settings.value(u'width',
QtCore.QVariant(self.screens.current[u'size'].width())).toInt()[0])
settings.endGroup()
self.customXValueEdit.setEnabled(self.overrideCheckBox.isChecked())
self.customYValueEdit.setEnabled(self.overrideCheckBox.isChecked())
@ -391,13 +323,13 @@ class GeneralTab(SettingsTab):
settings.setValue(u'songselect password',
QtCore.QVariant(self.passwordEdit.displayText()))
settings.setValue(u'x position',
QtCore.QVariant(self.customXValueEdit.text()))
QtCore.QVariant(self.customXValueEdit.value()))
settings.setValue(u'y position',
QtCore.QVariant(self.customYValueEdit.text()))
QtCore.QVariant(self.customYValueEdit.value()))
settings.setValue(u'height',
QtCore.QVariant(self.customHeightValueEdit.text()))
QtCore.QVariant(self.customHeightValueEdit.value()))
settings.setValue(u'width',
QtCore.QVariant(self.customWidthValueEdit.text()))
QtCore.QVariant(self.customWidthValueEdit.value()))
settings.setValue(u'override position',
QtCore.QVariant(self.overrideCheckBox.isChecked()))
settings.endGroup()
@ -421,10 +353,10 @@ class GeneralTab(SettingsTab):
# Reset screens after initial definition
if self.overrideChanged:
self.screens.override[u'size'] = QtCore.QRect(
int(self.customXValueEdit.validText()),
int(self.customYValueEdit.validText()),
int(self.customWidthValueEdit.validText()),
int(self.customHeightValueEdit.validText()))
self.customXValueEdit.value(),
self.customYValueEdit.value(),
self.customWidthValueEdit.value(),
self.customHeightValueEdit.value())
if self.overrideCheckBox.isChecked():
self.screens.set_override_display()
else:

View File

@ -110,7 +110,7 @@ class MainDisplay(DisplayWidget):
Phonon.createPath(self.mediaObject, self.audio)
QtCore.QObject.connect(self.mediaObject,
QtCore.SIGNAL(u'stateChanged(Phonon::State, Phonon::State)'),
self.videoStart)
self.videoState)
QtCore.QObject.connect(self.mediaObject,
QtCore.SIGNAL(u'finished()'),
self.videoFinished)
@ -378,11 +378,13 @@ class MainDisplay(DisplayWidget):
Receiver.send_message(u'maindisplay_active')
return self.preview()
def videoStart(self, newState, oldState):
def videoState(self, newState, oldState):
"""
Start the video at a predetermined point.
"""
if newState == Phonon.PlayingState:
if newState == Phonon.PlayingState \
and oldState != Phonon.PausedState \
and self.serviceItem.start_time > 0:
# set start time in milliseconds
self.mediaObject.seek(self.serviceItem.start_time * 1000)

View File

@ -46,7 +46,6 @@ class SlideList(QtGui.QTableWidget):
QtGui.QTableWidget.__init__(self, parent.controller)
self.parent = parent
class SlideController(QtGui.QWidget):
"""
SlideController is the slide controller widget. This widget is what the
@ -117,7 +116,8 @@ class SlideController(QtGui.QWidget):
self.previewListWidget.setColumnWidth(0, self.controller.width())
self.previewListWidget.isLive = self.isLive
self.previewListWidget.setObjectName(u'PreviewListWidget')
self.previewListWidget.setSelectionBehavior(1)
self.previewListWidget.setSelectionBehavior(
QtGui.QAbstractItemView.SelectRows)
self.previewListWidget.setSelectionMode(
QtGui.QAbstractItemView.SingleSelection)
self.previewListWidget.setEditTriggers(
@ -857,6 +857,7 @@ class SlideController(QtGui.QWidget):
self.serviceItem.bg_image_bytes = None
self.slidePreview.setPixmap(QtGui.QPixmap.fromImage(frame))
self.selectedRow = row
self.__checkUpdateSelectedSlide(row)
Receiver.send_message(u'slidecontroller_%s_changed' % self.typePrefix,
row)

View File

@ -424,12 +424,12 @@ class ThemeManager(QtGui.QWidget):
unicode(translate('OpenLP.ThemeManager',
'OpenLP Themes (*.theme *.otz)')))
log.info(u'New Themes %s', unicode(files))
if not files:
return
Receiver.send_message(u'cursor_busy')
if files:
for file in files:
SettingsManager.set_last_dir(
self.settingsSection, unicode(file))
self.unzipTheme(file, self.path)
for file in files:
SettingsManager.set_last_dir(self.settingsSection, unicode(file))
self.unzipTheme(file, self.path)
self.loadThemes()
Receiver.send_message(u'cursor_normal')
@ -502,16 +502,16 @@ class ThemeManager(QtGui.QWidget):
def unzipTheme(self, filename, dir):
"""
Unzip the theme, remove the preview file if stored
Generate a new preview fileCheck the XML theme version and upgrade if
Generate a new preview file. Check the XML theme version and upgrade if
necessary.
"""
log.debug(u'Unzipping theme %s', filename)
filename = unicode(filename)
zip = None
outfile = None
filexml = None
try:
zip = zipfile.ZipFile(filename)
filexml = None
themename = None
for file in zip.namelist():
ucsfile = file_is_unicode(file)
@ -547,7 +547,7 @@ class ThemeManager(QtGui.QWidget):
else:
outfile = open(fullpath, u'wb')
outfile.write(zip.read(file))
except (IOError, NameError):
except (IOError, NameError, zipfile.BadZipfile):
critical_error_message_box(
translate('OpenLP.ThemeManager', 'Validation Error'),
translate('OpenLP.ThemeManager', 'File is not a valid theme.'))
@ -562,7 +562,9 @@ class ThemeManager(QtGui.QWidget):
if filexml:
theme = self._createThemeFromXml(filexml, self.path)
self.generateAndSaveImage(dir, themename, theme)
else:
# Only show the error message, when IOError was not raised (in this
# case the error message has already been shown).
elif zip is not None:
critical_error_message_box(
translate('OpenLP.ThemeManager', 'Validation Error'),
translate('OpenLP.ThemeManager',

View File

@ -268,6 +268,7 @@ class SearchResults(object):
return len(self.verselist) > 0
from versereferencelist import VerseReferenceList
from manager import BibleManager
from biblestab import BiblesTab
from mediaitem import BibleMediaItem

View File

@ -35,7 +35,7 @@ from openlp.core.lib.ui import UiStrings, add_widget_completer, \
media_item_combo_box, critical_error_message_box
from openlp.plugins.bibles.forms import BibleImportForm
from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, \
get_reference_match
VerseReferenceList, get_reference_match
log = logging.getLogger(__name__)
@ -637,6 +637,7 @@ class BibleMediaItem(MediaManagerItem):
old_chapter = -1
raw_slides = []
raw_title = []
verses = VerseReferenceList()
for item in items:
bitem = self.listView.item(item.row())
book = self._decodeQtObject(bitem, 'book')
@ -653,15 +654,9 @@ class BibleMediaItem(MediaManagerItem):
second_permissions = \
self._decodeQtObject(bitem, 'second_permissions')
second_text = self._decodeQtObject(bitem, 'second_text')
verses.add(book, chapter, verse, version, copyright, permissions)
verse_text = self.formatVerse(old_chapter, chapter, verse)
footer = u'%s (%s %s %s)' % (book, version, copyright, permissions)
if footer not in service_item.raw_footer:
service_item.raw_footer.append(footer)
if second_bible:
footer = u'%s (%s %s %s)' % (book, second_version,
second_copyright, second_permissions)
if footer not in service_item.raw_footer:
service_item.raw_footer.append(footer)
bible_text = u'%s %s\n\n%s %s' % (verse_text, text,
verse_text, second_text)
raw_slides.append(bible_text.rstrip())
@ -684,6 +679,12 @@ class BibleMediaItem(MediaManagerItem):
start_item = item
old_item = item
old_chapter = chapter
# Add footer
service_item.raw_footer.append(verses.format_verses())
if second_bible:
verses.add_version(second_version, second_copyright,
second_permissions)
service_item.raw_footer.append(verses.format_versions())
raw_title.append(self.formatTitle(start_item, item))
# If there are no more items we check whether we have to add bible_text.
if bible_text:

View File

@ -0,0 +1,99 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat, #
# Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon #
# Tibble, Carsten Tinggaard, Frode Woldsund #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
class VerseReferenceList(object):
"""
The VerseReferenceList class encapsulates a list of verse references, but
maintains the order in which they were added.
"""
def __init__(self):
self.verse_list = []
self.version_list = []
self.current_index = -1
def add(self, book, chapter, verse, version, copyright, permission):
self.add_version(version, copyright, permission)
if not self.verse_list or \
self.verse_list[self.current_index][u'book'] != book:
self.verse_list.append({u'version': version, u'book': book,
u'chapter': chapter, u'start': verse, u'end': verse})
self.current_index += 1
elif self.verse_list[self.current_index][u'chapter'] != chapter:
self.verse_list.append({u'version': version, u'book': book,
u'chapter': chapter, u'start': verse, u'end': verse})
self.current_index += 1
elif (self.verse_list[self.current_index][u'end'] + 1) == verse:
self.verse_list[self.current_index][u'end'] = verse
else:
self.verse_list.append({u'version': version, u'book': book,
u'chapter': chapter, u'start': verse, u'end': verse})
self.current_index += 1
def add_version(self, version, copyright, permission):
for bible_version in self.version_list:
if bible_version[u'version'] == version:
return
self.version_list.append({u'version': version, u'copyright': copyright,
u'permission': permission})
def format_verses(self):
result = u''
for index, verse in enumerate(self.verse_list):
if index == 0:
result = u'%s %s:%s' % (verse[u'book'], verse[u'chapter'],
verse[u'start'])
if verse[u'start'] != verse[u'end']:
result = u'%s-%s' % (result, verse[u'end'])
continue
prev = index - 1
if self.verse_list[prev][u'version'] != verse[u'version']:
result = u'%s (%s)' % (result, verse[u'version'])
result = result + u', '
if self.verse_list[prev][u'book'] != verse[u'book']:
result = u'%s%s %s:' % (result, verse[u'book'],
verse[u'chapter'])
elif self.verse_list[prev][u'chapter'] != verse[u'chapter']:
result = u'%s%s:' % (result, verse[u'chapter'])
result = result + str(verse[u'start'])
if verse[u'start'] != verse[u'end']:
result = u'%s-%s' % (result, verse[u'end'])
if len(self.version_list) > 1:
result = u'%s (%s)' % (result, verse[u'version'])
return result
def format_versions(self):
result = u''
for index, version in enumerate(self.version_list):
if index > 0:
if result[-1] not in [u';', u',', u'.']:
result = result + u';'
result = result + u' '
result = u'%s%s, %s' % (result, version[u'version'],
version[u'copyright'])
if version[u'permission'].strip():
result = result + u', ' + version[u'permission']
return result

View File

@ -220,10 +220,7 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
Removes the current row from the list.
"""
self.slideListView.takeItem(self.slideListView.currentRow())
if self.slideListView.currentRow() == 0:
self.upButton.setEnabled(False)
if self.slideListView.currentRow() == self.slideListView.count():
self.downButton.setEnabled(False)
self.onCurrentRowChanged(self.slideListView.currentRow())
def onCurrentRowChanged(self, row):
"""

View File

@ -24,6 +24,7 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from datetime import datetime
import logging
import os
@ -35,7 +36,7 @@ from openlp.core.lib.ui import UiStrings, critical_error_message_box
from PyQt4.phonon import Phonon
log = logging.getLogger(__name__)
class MediaMediaItem(MediaManagerItem):
"""
This is the custom media manager item for Media Slides.
@ -53,9 +54,6 @@ class MediaMediaItem(MediaManagerItem):
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'video_background_replaced'),
self.videobackgroundReplaced)
QtCore.QObject.connect(self.mediaObject,
QtCore.SIGNAL(u'stateChanged(Phonon::State, Phonon::State)'),
self.videoStart)
def retranslateUi(self):
self.onNewPrompt = translate('MediaPlugin.MediaItem', 'Select Media')
@ -124,36 +122,67 @@ class MediaMediaItem(MediaManagerItem):
if item is None:
return False
filename = unicode(item.data(QtCore.Qt.UserRole).toString())
if os.path.exists(filename):
self.mediaState = None
self.mediaObject.stop()
self.mediaObject.clearQueue()
self.mediaObject.setCurrentSource(Phonon.MediaSource(filename))
self.mediaObject.play()
service_item.title = unicode(self.plugin.nameStrings[u'singular'])
service_item.add_capability(ItemCapabilities.RequiresMedia)
# force a nonexistent theme
service_item.theme = -1
frame = u':/media/image_clapperboard.png'
(path, name) = os.path.split(filename)
file_size = os.path.getsize(filename)
# File too big for processing
if file_size <= 52428800: # 50MiB
while not self.mediaState:
Receiver.send_message(u'openlp_process_events')
service_item.media_length = self.mediaLength
service_item.add_capability(
ItemCapabilities.AllowsVariableStartTime)
service_item.add_from_command(path, name, frame)
return True
else:
if not os.path.exists(filename):
# File is no longer present
critical_error_message_box(
translate('MediaPlugin.MediaItem', 'Missing Media File'),
unicode(translate('MediaPlugin.MediaItem',
'The file %s no longer exists.')) % filename)
return False
self.mediaObject.stop()
self.mediaObject.clearQueue()
self.mediaObject.setCurrentSource(Phonon.MediaSource(filename))
if not self.mediaStateWait(Phonon.StoppedState):
# Due to string freeze, borrow a message from presentations
# This will be corrected in 1.9.6
critical_error_message_box(
translate('PresentationPlugin.MediaItem', 'Unsupported File'),
unicode(translate('PresentationPlugin.MediaItem',
'Unsupported File')))
return False
# File too big for processing
if os.path.getsize(filename) <= 52428800: # 50MiB
self.mediaObject.play()
if not self.mediaStateWait(Phonon.PlayingState) \
or self.mediaObject.currentSource().type() \
== Phonon.MediaSource.Invalid:
# Due to string freeze, borrow a message from presentations
# This will be corrected in 1.9.6
self.mediaObject.stop()
critical_error_message_box(
translate('PresentationPlugin.MediaItem',
'Unsupported File'),
unicode(translate('PresentationPlugin.MediaItem',
'Unsupported File')))
return False
self.mediaLength = self.mediaObject.totalTime() / 1000
self.mediaObject.stop()
service_item.media_length = self.mediaLength
service_item.add_capability(
ItemCapabilities.AllowsVariableStartTime)
service_item.title = unicode(self.plugin.nameStrings[u'singular'])
service_item.add_capability(ItemCapabilities.RequiresMedia)
# force a non-existent theme
service_item.theme = -1
frame = u':/media/image_clapperboard.png'
(path, name) = os.path.split(filename)
service_item.add_from_command(path, name, frame)
return True
def mediaStateWait(self, mediaState):
"""
Wait for the video to change its state
Wait no longer than 5 seconds.
"""
start = datetime.now()
while self.mediaObject.state() != mediaState:
if self.mediaObject.state() == Phonon.ErrorState:
return False
Receiver.send_message(u'openlp_process_events')
if (datetime.now() - start).seconds > 5:
return False
return True
def initialise(self):
self.listView.clear()
self.listView.setIconSize(QtCore.QSize(88, 50))
@ -181,12 +210,3 @@ class MediaMediaItem(MediaManagerItem):
item_name.setIcon(build_icon(img))
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file))
self.listView.addItem(item_name)
def videoStart(self, newState, oldState):
"""
Start the video at a predetermined point.
"""
if newState == Phonon.PlayingState:
self.mediaState = newState
self.mediaLength = self.mediaObject.totalTime()/1000
self.mediaObject.stop()

View File

@ -49,11 +49,13 @@ class MediaPlugin(Plugin):
u'audio/ac3': [u'.ac3'],
u'audio/flac': [u'.flac'],
u'audio/x-m4a': [u'.m4a'],
u'audio/midi': [u'.mid', u'.midi'],
u'audio/x-mp3': [u'.mp3'],
u'audio/mpeg': [u'.mp3', u'.mp2', u'.mpga', u'.mpega', u'.m4a'],
u'audio/qcelp': [u'.qcp'],
u'audio/x-wma': [u'.wma'],
u'audio/x-ms-wma': [u'.wma'],
u'video/x-flv': [u'.flv'],
u'video/x-matroska': [u'.mpv', u'.mkv'],
u'video/x-wmv': [u'.wmv'],
u'video/x-ms-wmv': [u'.wmv']}

View File

@ -80,8 +80,7 @@ class PowerpointController(PresentationController):
log.debug(u'start_process')
if not self.process:
self.process = Dispatch(u'PowerPoint.Application')
if float(self.process.Version) < 13:
self.process.Visible = True
self.process.Visible = True
self.process.WindowState = 2
def kill(self):

View File

@ -30,19 +30,32 @@ from ctypes import *
from ctypes.wintypes import RECT
class PPTViewer(QtGui.QWidget):
"""
Standalone Test Harness for the pptviewlib library
"""
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.pptid = -1
self.setWindowTitle(u'PowerPoint Viewer Test')
PPTLabel = QtGui.QLabel(u'Open PowerPoint file')
slideLabel = QtGui.QLabel(u'Go to slide #')
self.PPTEdit = QtGui.QLineEdit()
ppt_label = QtGui.QLabel(u'Open PowerPoint file')
slide_label = QtGui.QLabel(u'Go to slide #')
self.pptEdit = QtGui.QLineEdit()
self.slideEdit = QtGui.QLineEdit()
x_label = QtGui.QLabel(u'X pos')
y_label = QtGui.QLabel(u'Y pos')
width_label = QtGui.QLabel(u'Width')
height_label = QtGui.QLabel(u'Height')
self.xEdit = QtGui.QLineEdit(u'100')
self.yEdit = QtGui.QLineEdit(u'100')
self.widthEdit = QtGui.QLineEdit(u'900')
self.heightEdit = QtGui.QLineEdit(u'700')
self.total = QtGui.QLabel()
PPTBtn = QtGui.QPushButton(u'Open')
PPTDlgBtn = QtGui.QPushButton(u'...')
slideBtn = QtGui.QPushButton(u'Go')
ppt_btn = QtGui.QPushButton(u'Open')
ppt_dlg_btn = QtGui.QPushButton(u'...')
folder_label = QtGui.QLabel(u'Slide .bmp path')
self.folderEdit = QtGui.QLineEdit(u'slide')
slide_btn = QtGui.QPushButton(u'Go')
prev = QtGui.QPushButton(u'Prev')
next = QtGui.QPushButton(u'Next')
blank = QtGui.QPushButton(u'Blank')
@ -51,122 +64,149 @@ class PPTViewer(QtGui.QWidget):
close = QtGui.QPushButton(u'Close')
resume = QtGui.QPushButton(u'Resume')
stop = QtGui.QPushButton(u'Stop')
pptwindow = QtGui.QWidget()
grid = QtGui.QGridLayout()
grid.addWidget(PPTLabel, 0, 0)
grid.addWidget(self.PPTEdit, 0, 1)
grid.addWidget(PPTDlgBtn, 0, 2)
grid.addWidget(PPTBtn, 0, 3)
grid.addWidget(slideLabel, 1, 0)
grid.addWidget(self.slideEdit, 1, 1)
grid.addWidget(slideBtn, 1, 3)
grid.addWidget(prev, 2, 0)
grid.addWidget(next, 2, 1)
grid.addWidget(blank, 3, 0)
grid.addWidget(unblank, 3, 1)
grid.addWidget(restart, 4, 0)
grid.addWidget(close, 4, 1)
grid.addWidget(stop, 5, 0)
grid.addWidget(resume, 5, 1)
grid.addWidget(pptwindow, 6, 0, 10, 3)
self.connect(PPTBtn, QtCore.SIGNAL(u'clicked()'), self.OpenClick)
self.connect(PPTDlgBtn, QtCore.SIGNAL(u'clicked()'), self.OpenDialog)
self.connect(slideBtn, QtCore.SIGNAL(u'clicked()'), self.GotoClick)
self.connect(prev, QtCore.SIGNAL(u'clicked()'), self.PrevClick)
self.connect(next, QtCore.SIGNAL(u'clicked()'), self.NextClick)
self.connect(blank, QtCore.SIGNAL(u'clicked()'), self.BlankClick)
self.connect(unblank, QtCore.SIGNAL(u'clicked()'), self.UnblankClick)
self.connect(restart, QtCore.SIGNAL(u'clicked()'), self.RestartClick)
self.connect(close, QtCore.SIGNAL(u'clicked()'), self.CloseClick)
self.connect(stop, QtCore.SIGNAL(u'clicked()'), self.StopClick)
self.connect(resume, QtCore.SIGNAL(u'clicked()'), self.ResumeClick)
row = 0
grid.addWidget(folder_label, 0, 0)
grid.addWidget(self.folderEdit, 0, 1)
row = row + 1
grid.addWidget(x_label, row, 0)
grid.addWidget(self.xEdit, row, 1)
grid.addWidget(y_label, row, 2)
grid.addWidget(self.yEdit, row, 3)
row = row + 1
grid.addWidget(width_label, row, 0)
grid.addWidget(self.widthEdit, row, 1)
grid.addWidget(height_label, row, 2)
grid.addWidget(self.heightEdit, row, 3)
row = row + 1
grid.addWidget(ppt_label, row, 0)
grid.addWidget(self.pptEdit, row, 1)
grid.addWidget(ppt_dlg_btn, row, 2)
grid.addWidget(ppt_btn, row, 3)
row = row + 1
grid.addWidget(slide_label, row, 0)
grid.addWidget(self.slideEdit, row, 1)
grid.addWidget(slide_btn, row, 2)
row = row + 1
grid.addWidget(prev, row, 0)
grid.addWidget(next, row, 1)
row = row + 1
grid.addWidget(blank, row, 0)
grid.addWidget(unblank, row, 1)
row = row + 1
grid.addWidget(restart, row, 0)
grid.addWidget(close, row, 1)
row = row + 1
grid.addWidget(stop, row, 0)
grid.addWidget(resume, row, 1)
self.connect(ppt_btn, QtCore.SIGNAL(u'clicked()'), self.openClick)
self.connect(ppt_dlg_btn, QtCore.SIGNAL(u'clicked()'), self.openDialog)
self.connect(slide_btn, QtCore.SIGNAL(u'clicked()'), self.gotoClick)
self.connect(prev, QtCore.SIGNAL(u'clicked()'), self.prevClick)
self.connect(next, QtCore.SIGNAL(u'clicked()'), self.nextClick)
self.connect(blank, QtCore.SIGNAL(u'clicked()'), self.blankClick)
self.connect(unblank, QtCore.SIGNAL(u'clicked()'), self.unblankClick)
self.connect(restart, QtCore.SIGNAL(u'clicked()'), self.restartClick)
self.connect(close, QtCore.SIGNAL(u'clicked()'), self.closeClick)
self.connect(stop, QtCore.SIGNAL(u'clicked()'), self.stopClick)
self.connect(resume, QtCore.SIGNAL(u'clicked()'), self.resumeClick)
self.setLayout(grid)
self.resize(300, 150)
def PrevClick(self):
if self.pptid<0: return
pptdll.PrevStep(self.pptid)
self.UpdateCurrSlide()
def prevClick(self):
if self.pptid < 0:
return
self.pptdll.PrevStep(self.pptid)
self.updateCurrSlide()
app.processEvents()
def NextClick(self):
if(self.pptid<0): return
pptdll.NextStep(self.pptid)
self.UpdateCurrSlide()
def nextClick(self):
if self.pptid < 0:
return
self.pptdll.NextStep(self.pptid)
self.updateCurrSlide()
app.processEvents()
def BlankClick(self):
if(self.pptid<0): return
pptdll.Blank(self.pptid)
def blankClick(self):
if self.pptid < 0:
return
self.pptdll.Blank(self.pptid)
app.processEvents()
def UnblankClick(self):
if(self.pptid<0): return
pptdll.Unblank(self.pptid)
def unblankClick(self):
if self.pptid < 0:
return
self.pptdll.Unblank(self.pptid)
app.processEvents()
def RestartClick(self):
if(self.pptid<0): return
pptdll.RestartShow(self.pptid)
self.UpdateCurrSlide()
def restartClick(self):
if self.pptid < 0:
return
self.pptdll.RestartShow(self.pptid)
self.updateCurrSlide()
app.processEvents()
def StopClick(self):
if(self.pptid<0): return
pptdll.Stop(self.pptid)
def stopClick(self):
if self.pptid < 0:
return
self.pptdll.Stop(self.pptid)
app.processEvents()
def ResumeClick(self):
if(self.pptid<0): return
pptdll.Resume(self.pptid)
def resumeClick(self):
if self.pptid < 0:
return
self.pptdll.Resume(self.pptid)
app.processEvents()
def CloseClick(self):
if(self.pptid<0): return
pptdll.ClosePPT(self.pptid)
def closeClick(self):
if self.pptid < 0:
return
self.pptdll.ClosePPT(self.pptid)
self.pptid = -1
app.processEvents()
def OpenClick(self):
def openClick(self):
oldid = self.pptid;
rect = RECT(100,100,900,700)
filename = str(self.PPTEdit.text().replace(u'/', u'\\'))
print filename
self.pptid = pptdll.OpenPPT(filename, None, rect, 'c:\\temp\\slide')
print "id: " + unicode(self.pptid)
if oldid>=0:
pptdll.ClosePPT(oldid);
slides = pptdll.GetSlideCount(self.pptid)
print "slidecount: " + unicode(slides)
self.total.setNum(pptdll.GetSlideCount(self.pptid))
self.UpdateCurrSlide()
rect = RECT(int(self.xEdit.text()), int(self.yEdit.text()),
int(self.widthEdit.text()), int(self.heightEdit.text()))
filename = str(self.pptEdit.text().replace(u'/', u'\\'))
folder = str(self.folderEdit.text().replace(u'/', u'\\'))
print filename, folder
self.pptid = self.pptdll.OpenPPT(filename, None, rect, folder)
print u'id: ' + unicode(self.pptid)
if oldid >= 0:
self.pptdll.ClosePPT(oldid);
slides = self.pptdll.GetSlideCount(self.pptid)
print u'slidecount: ' + unicode(slides)
self.total.setNum(self.pptdll.GetSlideCount(self.pptid))
self.updateCurrSlide()
def UpdateCurrSlide(self):
if(self.pptid<0): return
slide = unicode(pptdll.GetCurrentSlide(self.pptid))
print "currslide: " + slide
def updateCurrSlide(self):
if self.pptid < 0:
return
slide = unicode(self.pptdll.GetCurrentSlide(self.pptid))
print u'currslide: ' + slide
self.slideEdit.setText(slide)
app.processEvents()
def GotoClick(self):
if(self.pptid<0): return
def gotoClick(self):
if self.pptid < 0:
return
print self.slideEdit.text()
pptdll.GotoSlide(self.pptid, int(self.slideEdit.text()))
self.UpdateCurrSlide()
self.pptdll.GotoSlide(self.pptid, int(self.slideEdit.text()))
self.updateCurrSlide()
app.processEvents()
def OpenDialog(self):
self.PPTEdit.setText(QtGui.QFileDialog.getOpenFileName(self, 'Open file'))
def openDialog(self):
self.pptEdit.setText(QtGui.QFileDialog.getOpenFileName(self,
u'Open file'))
if __name__ == '__main__':
#pptdll = cdll.LoadLibrary(r'C:\Documents and Settings\jonathan\Desktop\pptviewlib.dll')
pptdll = cdll.LoadLibrary(r'pptviewlib.dll')
pptdll.SetDebug(1)
print "Begin..."
print u'Begin...'
app = QtGui.QApplication(sys.argv)
qb = PPTViewer()
qb.show()
window = PPTViewer()
window.pptdll = pptdll
window.show()
sys.exit(app.exec_())

File diff suppressed because it is too large Load Diff

View File

@ -1,55 +1,84 @@
/******************************************************************************
* PptViewLib - PowerPoint Viewer 2003/2007 Controller *
* OpenLP - Open Source Lyrics Projection *
* --------------------------------------------------------------------------- *
* Copyright (c) 2008-2011 Raoul Snyman *
* Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael *
* Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat, *
* Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon *
* Tibble, Carsten Tinggaard, Frode Woldsund *
* --------------------------------------------------------------------------- *
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation; version 2 of the License. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., 59 *
* Temple Place, Suite 330, Boston, MA 02111-1307 USA *
******************************************************************************/
#define DllExport extern "C" __declspec( dllexport )
enum PPTVIEWSTATE { PPT_CLOSED, PPT_STARTED, PPT_OPENED, PPT_LOADED, PPT_CLOSING};
#define DEBUG(...) if (debug) printf(__VA_ARGS__)
DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect, char *previewpath);
enum PPTVIEWSTATE {PPT_CLOSED, PPT_STARTED, PPT_OPENED, PPT_LOADED,
PPT_CLOSING};
DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect,
char *previewPath);
DllExport BOOL CheckInstalled();
DllExport void ClosePPT(int id);
DllExport int GetCurrentSlide(int id);
DllExport int GetSlideCount(int id);
DllExport void NextStep(int id);
DllExport void PrevStep(int id);
DllExport void GotoSlide(int id, int slideno);
DllExport void GotoSlide(int id, int slide_no);
DllExport void RestartShow(int id);
DllExport void Blank(int id);
DllExport void Unblank(int id);
DllExport void Stop(int id);
DllExport void Resume(int id);
DllExport void SetDebug(BOOL onoff);
DllExport void SetDebug(BOOL onOff);
LRESULT CALLBACK CbtProc(int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK CwpProc(int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam);
BOOL GetPPTViewerPath(char *pptviewerpath, int strsize);
HBITMAP CaptureWindow (HWND hWnd);
VOID SaveBitmap (CHAR* filename, HBITMAP hBmp) ;
BOOL GetPPTViewerPath(char *pptViewerPath, int stringSize);
HBITMAP CaptureWindow(HWND hWnd);
VOID SaveBitmap(CHAR* filename, HBITMAP hBmp) ;
VOID CaptureAndSaveWindow(HWND hWnd, CHAR* filename);
BOOL GetPPTInfo(int id);
BOOL SavePPTInfo(int id);
void Unhook(int id);
#define MAX_PPTOBJS 50
#define MAX_PPTS 16
#define MAX_SLIDES 256
struct PPTVIEWOBJ
struct PPTVIEW
{
HHOOK hook;
HHOOK mhook;
HWND hWnd;
HWND hWnd2;
HWND hParentWnd;
HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwThreadId;
RECT rect;
int slideCount;
int currentSlide;
int firstSlideSteps;
int steps;
char filename[MAX_PATH];
char previewpath[MAX_PATH];
PPTVIEWSTATE state;
HHOOK hook;
HHOOK msgHook;
HWND hWnd;
HWND hWnd2;
HWND hParentWnd;
HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwThreadId;
RECT rect;
int slideCount;
int currentSlide;
int firstSlideSteps;
int lastSlideSteps;
int steps;
int guess;
char filename[MAX_PATH];
char previewPath[MAX_PATH];
int slideNos[MAX_SLIDES];
PPTVIEWSTATE state;
};

View File

@ -71,6 +71,8 @@ class Ui_EditSongDialog(object):
self.verseListWidget.setColumnCount(1)
self.verseListWidget.setSelectionBehavior(
QtGui.QAbstractItemView.SelectRows)
self.verseListWidget.setSelectionMode(
QtGui.QAbstractItemView.SingleSelection)
self.verseListWidget.setEditTriggers(
QtGui.QAbstractItemView.NoEditTriggers)
self.verseListWidget.setObjectName(u'verseListWidget')

View File

@ -543,8 +543,9 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
def onVerseDeleteButtonClicked(self):
self.verseListWidget.removeRow(self.verseListWidget.currentRow())
self.verseEditButton.setEnabled(False)
self.verseDeleteButton.setEnabled(False)
if not self.verseListWidget.selectedItems():
self.verseEditButton.setEnabled(False)
self.verseDeleteButton.setEnabled(False)
def _validate_song(self):
"""

View File

@ -271,6 +271,37 @@ def clean_song(manager, song):
verses = SongXML().get_verses(song.lyrics)
lyrics = u' '.join([whitespace.sub(u' ', verse[1]) for verse in verses])
song.search_lyrics = lyrics.lower()
# We need a new and clean SongXML instance.
sxml = SongXML()
# Rebuild the song's verses, to remove any wrong verse names (for example
# translated ones), which might have been added prior to 1.9.5.
# List for later comparison.
compare_order = []
for verse in verses:
type = VerseType.Tags[VerseType.from_loose_input(verse[0][u'type'])]
sxml.add_verse_to_lyrics(
type,
verse[0][u'label'],
verse[1],
verse[0][u'lang'] if verse[0].has_key(u'lang') else None
)
compare_order.append((u'%s%s' % (type, verse[0][u'label'])).upper())
song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
# Rebuild the verse order, to convert translated verse tags, which might
# have been added prior to 1.9.5.
order = song.verse_order.strip().split()
new_order = []
for verse_def in order:
new_order.append((u'%s%s' % (
VerseType.Tags[VerseType.from_loose_input(verse_def[0])],
verse_def[1:])).upper()
)
song.verse_order = u' '.join(new_order)
# Check if the verse order contains tags for verses which do not exist.
for order in new_order:
if order not in compare_order:
song.verse_order = u''
break
# The song does not have any author, add one.
if not song.authors:
name = SongStrings.AuthorUnknown

View File

@ -461,5 +461,5 @@ class SongMediaItem(MediaManagerItem):
"""
Locale aware collation of song titles
"""
return locale.strcoll(unicode(song_1.title.lower()),
return locale.strcoll(unicode(song_1.title.lower()),
unicode(song_2.title.lower()))

View File

@ -309,7 +309,7 @@ class SofImport(OooImport):
self.add_verse(lyrics, tag)
if not self.is_chorus and u'C1' in self.verse_order_list_generated:
self.verse_order_list_generated.append(u'C1')
self.verse_order_list_generated_useful = True
self.verse_order_list_generated_useful = True
def uncap_text(self, text):
"""

View File

@ -34,31 +34,32 @@ import os
import re
from openlp.core.ui.wizard import WizardStrings
from openlp.plugins.songs.lib import VerseType
from openlp.plugins.songs.lib.songimport import SongImport
log = logging.getLogger(__name__)
class SongBeamerTypes(object):
MarkTypes = {
u'Refrain': u'C',
u'Chorus': u'C',
u'Vers': u'V',
u'Verse': u'V',
u'Strophe': u'V',
u'Intro': u'I',
u'Coda': u'E',
u'Ending': u'E',
u'Bridge': u'B',
u'Interlude': u'B',
u'Zwischenspiel': u'B',
u'Pre-Chorus': u'P',
u'Pre-Refrain': u'P',
u'Pre-Bridge': u'O',
u'Pre-Coda': u'O',
u'Unbekannt': u'O',
u'Unknown': u'O',
u'Unbenannt': u'O'
}
u'Refrain': VerseType.Tags[VerseType.Chorus],
u'Chorus': VerseType.Tags[VerseType.Chorus],
u'Vers': VerseType.Tags[VerseType.Verse],
u'Verse': VerseType.Tags[VerseType.Verse],
u'Strophe': VerseType.Tags[VerseType.Verse],
u'Intro': VerseType.Tags[VerseType.Intro],
u'Coda': VerseType.Tags[VerseType.Ending],
u'Ending': VerseType.Tags[VerseType.Ending],
u'Bridge': VerseType.Tags[VerseType.Bridge],
u'Interlude': VerseType.Tags[VerseType.Bridge],
u'Zwischenspiel': VerseType.Tags[VerseType.Bridge],
u'Pre-Chorus': VerseType.Tags[VerseType.PreChorus],
u'Pre-Refrain': VerseType.Tags[VerseType.PreChorus],
u'Pre-Bridge': VerseType.Tags[VerseType.Other],
u'Pre-Coda': VerseType.Tags[VerseType.Other],
u'Unbekannt': VerseType.Tags[VerseType.Other],
u'Unknown': VerseType.Tags[VerseType.Other],
u'Unbenannt': VerseType.Tags[VerseType.Other]
}
class SongBeamerImport(SongImport):
@ -84,7 +85,7 @@ class SongBeamerImport(SongImport):
# TODO: check that it is a valid SongBeamer file
self.set_defaults()
self.current_verse = u''
self.current_verse_type = u'V'
self.current_verse_type = VerseType.Tags[VerseType.Verse]
read_verses = False
file_name = os.path.split(file)[1]
self.import_wizard.incrementProgressBar(
@ -111,7 +112,7 @@ class SongBeamerImport(SongImport):
self.add_verse(self.current_verse,
self.current_verse_type)
self.current_verse = u''
self.current_verse_type = u'V'
self.current_verse_type = VerseType.Tags[VerseType.Verse]
read_verses = True
verse_start = True
elif read_verses:
@ -157,7 +158,7 @@ class SongBeamerImport(SongImport):
(u'<[/]?c.*?>', u''),
(u'<align.*?>', u''),
(u'<valign.*?>', u'')
]
]
for pair in tag_pairs:
self.current_verse = re.compile(pair[0]).sub(pair[1],
self.current_verse)

View File

@ -225,7 +225,7 @@ class SongImport(QtCore.QObject):
self.verse_counts[verse_def[0]] = int(verse_def[1:])
self.verses.append([verse_def, verse_text.rstrip(), lang])
self.verse_order_list_generated.append(verse_def)
def repeat_verse(self):
"""
Repeat the previous verse in the verse order

View File

@ -131,7 +131,7 @@ class SongShowPlusImport(SongImport):
lengthDescriptor, = struct.unpack("B", songData.read(1))
data = songData.read(lengthDescriptor)
if blockKey == TITLE:
self.title = unicode(data, u'cp1252')
self.title = unicode(data, u'cp1252')
elif blockKey == AUTHOR:
authors = data.split(" / ")
for author in authors:

View File

@ -31,7 +31,7 @@ The basic XML for storing the lyrics in the song database looks like this::
<?xml version="1.0" encoding="UTF-8"?>
<song version="1.0">
<lyrics>
<verse type="Chorus" label="1" lang="en">
<verse type="c" label="1" lang="en">
<![CDATA[ ... ]]>
</verse>
</lyrics>
@ -89,8 +89,8 @@ class SongXML(object):
Add a verse to the ``<lyrics>`` tag.
``type``
A string denoting the type of verse. Possible values are *Verse*,
*Chorus*, *Bridge*, *Pre-Chorus*, *Intro*, *Ending* and *Other*.
A string denoting the type of verse. Possible values are *v*,
*c*, *b*, *p*, *i*, *e* and *o*.
Any other type is **not** allowed, this also includes translated
types.
@ -128,8 +128,8 @@ class SongXML(object):
The returned list has the following format::
[[{'lang': 'en', 'type': 'Verse', 'label': '1'}, u"English verse"],
[{'lang': 'en', 'type': 'Chorus', 'label': '1'}, u"English chorus"]]
[[{'lang': 'en', 'type': 'v', 'label': '1'}, u"English verse"],
[{'lang': 'en', 'type': 'c', 'label': '1'}, u"English chorus"]]
"""
self.song_xml = None
if xml[:5] == u'<?xml':
@ -451,10 +451,12 @@ class OpenLyrics(object):
if text:
text += u'\n'
text += u'\n'.join([unicode(line) for line in lines.line])
verse_name = self._get(verse, u'name')
verse_type_index = VerseType.from_tag(verse_name[0])
verse_type = VerseType.Names[verse_type_index]
verse_number = re.compile(u'[a-zA-Z]*').sub(u'', verse_name)
verse_def = self._get(verse, u'name').lower()
if verse_def[0] in VerseType.Tags:
verse_tag = verse_def[0]
else:
verse_tag = VerseType.Tags[VerseType.Other]
verse_number = re.compile(u'[a-zA-Z]*').sub(u'', verse_def)
# OpenLyrics allows e. g. "c", but we need "c1". However, this does
# not correct the verse order.
if not verse_number:
@ -462,7 +464,7 @@ class OpenLyrics(object):
lang = None
if self._get(verse, u'lang'):
lang = self._get(verse, u'lang')
sxml.add_verse_to_lyrics(verse_type, verse_number, text, lang)
sxml.add_verse_to_lyrics(verse_tag, verse_number, text, lang)
song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
# Process verse order
if hasattr(properties, u'verseOrder'):

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -31,9 +31,9 @@ OutputDir=..\..\dist
OutputBaseFilename=OpenLP-{#RealVersion}-setup
Compression=lzma
SolidCompression=true
SetupIconFile=C:\Program Files\Inno Setup 5\Examples\Setup.ico
WizardImageFile=C:\Program Files\Inno Setup 5\WizModernImage-IS.bmp
WizardSmallImageFile=C:\Program Files\Inno Setup 5\WizModernSmallImage-IS.bmp
SetupIconFile=OpenLP.ico
WizardImageFile=WizImageBig.bmp
WizardSmallImageFile=WizImageSmall.bmp
[Languages]
Name: english; MessagesFile: compiler:Default.isl
@ -78,15 +78,6 @@ Name: {userappdata}\Microsoft\Internet Explorer\Quick Launch\{#AppName}; Filenam
Filename: {app}\{#AppExeName}; Description: {cm:LaunchProgram,{#AppName}}; Flags: nowait postinstall skipifsilent
[Registry]
Root: HKCU; SubKey: Software\OpenLP\OpenLP\alerts; ValueType: dword; ValueName: status; ValueData: $00000001
Root: HKCU; SubKey: Software\OpenLP\OpenLP\bibles; ValueType: dword; ValueName: status; ValueData: $00000001
Root: HKCU; SubKey: Software\OpenLP\OpenLP\custom; ValueType: dword; ValueName: status; ValueData: $00000001
Root: HKCU; SubKey: Software\OpenLP\OpenLP\images; ValueType: dword; ValueName: status; ValueData: $00000001
Root: HKCU; SubKey: Software\OpenLP\OpenLP\media; ValueType: dword; ValueName: status; ValueData: $00000001
Root: HKCU; SubKey: Software\OpenLP\OpenLP\presentations; ValueType: dword; ValueName: status; ValueData: $00000001
Root: HKCU; SubKey: Software\OpenLP\OpenLP\remotes; ValueType: dword; ValueName: status; ValueData: $00000000
Root: HKCU; SubKey: Software\OpenLP\OpenLP\songs; ValueType: dword; ValueName: status; ValueData: $00000001
Root: HKCU; SubKey: Software\OpenLP\OpenLP\songusage; ValueType: dword; ValueName: status; ValueData: $00000001
[Code]
function GetUninstallString(): String;

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

View File

@ -116,8 +116,15 @@ dist_path = os.path.join(branch_path, u'dist', u'OpenLP')
enchant_path = os.path.join(site_packages, u'enchant')
def update_code():
print u'Updating the code...'
os.chdir(branch_path)
print u'Reverting any changes to the code...'
bzr = Popen((u'bzr', u'revert'), stdout=PIPE)
output, error = bzr.communicate()
code = bzr.wait()
if code != 0:
print output
raise Exception(u'Error reverting the code')
print u'Updating the code...'
bzr = Popen((u'bzr', u'update'), stdout=PIPE)
output, error = bzr.communicate()
code = bzr.wait()

View File

@ -62,7 +62,41 @@ setup(
description="Open source Church presentation and lyrics projection application.",
long_description="""\
OpenLP (previously openlp.org) is free church presentation software, or lyrics projection software, used to display slides of songs, Bible verses, videos, images, and even presentations (if PowerPoint is installed) for church worship using a computer and a data projector.""",
classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
classifiers=[
'Development Status :: 4 - Beta',
'Environment :: MacOS X',
'Environment :: Win32 (MS Windows)',
'Environment :: X11 Applications',
'Environment :: X11 Applications :: Qt',
'Intended Audience :: End Users/Desktop',
'Intended Audience :: Religion',
'License :: OSI Approved :: GNU General Public License (GPL)',
'Natural Language :: Afrikaans',
'Natural Language :: Dutch',
'Natural Language :: English',
'Natural Language :: French',
'Natural Language :: German',
'Natural Language :: Hungarian',
'Natural Language :: Indonesian',
'Natural Language :: Japanese',
'Natural Language :: Norwegian',
'Natural Language :: Portuguese (Brazilian)',
'Natural Language :: Russian',
'Natural Language :: Swedish',
'Operating System :: MacOS :: MacOS X',
'Operating System :: Microsoft :: Windows',
'Operating System :: POSIX :: BSD :: FreeBSD',
'Operating System :: POSIX :: Linux',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Topic :: Desktop Environment :: Gnome',
'Topic :: Desktop Environment :: K Desktop Environment (KDE)',
'Topic :: Multimedia',
'Topic :: Multimedia :: Graphics :: Presentation',
'Topic :: Multimedia :: Sound/Audio',
'Topic :: Multimedia :: Video',
'Topic :: Religion'
], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
keywords='open source church presentation lyrics projection song bible display project',
author='Raoul Snyman',
author_email='raoulsnyman@openlp.org',