From 9d77444ddf9c380017c1ac7c846d6a1056253653 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Fri, 9 Jul 2010 21:27:18 +0100 Subject: [PATCH 001/108] Revert Changes --- openlp/core/ui/amendthemedialog.py | 21 +++++++-------------- openlp/core/ui/amendthemeform.py | 14 +------------- openlp/core/ui/thememanager.py | 2 +- 3 files changed, 9 insertions(+), 28 deletions(-) diff --git a/openlp/core/ui/amendthemedialog.py b/openlp/core/ui/amendthemedialog.py index e8b9c64e3..a5cd69610 100644 --- a/openlp/core/ui/amendthemedialog.py +++ b/openlp/core/ui/amendthemedialog.py @@ -646,20 +646,13 @@ class Ui_AmendThemeDialog(object): QtGui.QDialogButtonBox.Ok) self.ThemeButtonBox.setObjectName(u'ThemeButtonBox') self.AmendThemeLayout.addWidget(self.ThemeButtonBox) - self.SaveAsButton = QtGui.QPushButton( - translate('AmendThemeForm','Save &as')) - self.SaveAsButton.setCheckable(True) - self.SaveAsButton.setAutoDefault(False) - self.ThemeButtonBox.addButton(self.SaveAsButton, - QtGui.QDialogButtonBox.ActionRole) + self.retranslateUi(AmendThemeDialog) self.ThemeTabWidget.setCurrentIndex(0) QtCore.QObject.connect(self.ThemeButtonBox, QtCore.SIGNAL(u'accepted()'), AmendThemeDialog.accept) QtCore.QObject.connect(self.ThemeButtonBox, QtCore.SIGNAL(u'rejected()'), AmendThemeDialog.reject) - QtCore.QObject.connect(self.SaveAsButton, - QtCore.SIGNAL(u'clicked()'), AmendThemeDialog.saveAs) QtCore.QMetaObject.connectSlotsByName(AmendThemeDialog) AmendThemeDialog.setTabOrder(self.ThemeButtonBox, self.ThemeNameEdit) AmendThemeDialog.setTabOrder(self.ThemeNameEdit, self.ThemeTabWidget) @@ -855,19 +848,19 @@ class Ui_AmendThemeDialog(object): translate('AmendThemeForm', 'Alignment')) self.HorizontalLabel.setText( translate('AmendThemeForm', 'Horizontal align:')) - self.HorizontalComboBox.setItemText(0, + self.HorizontalComboBox.setItemText(0, translate('AmendThemeForm', 'Left')) - self.HorizontalComboBox.setItemText(1, + self.HorizontalComboBox.setItemText(1, translate('AmendThemeForm', 'Right')) - self.HorizontalComboBox.setItemText(2, + self.HorizontalComboBox.setItemText(2, translate('AmendThemeForm', 'Center')) self.VerticalLabel.setText( translate('AmendThemeForm', 'Vertical align:')) - self.VerticalComboBox.setItemText(0, + self.VerticalComboBox.setItemText(0, translate('AmendThemeForm', 'Top')) - self.VerticalComboBox.setItemText(1, + self.VerticalComboBox.setItemText(1, translate('AmendThemeForm', 'Middle')) - self.VerticalComboBox.setItemText(2, + self.VerticalComboBox.setItemText(2, translate('AmendThemeForm', 'Bottom')) self.TransitionGroupBox.setTitle( translate('AmendThemeForm', 'Slide Transition')) diff --git a/openlp/core/ui/amendthemeform.py b/openlp/core/ui/amendthemeform.py index f827b1639..1c2658dc3 100644 --- a/openlp/core/ui/amendthemeform.py +++ b/openlp/core/ui/amendthemeform.py @@ -137,12 +137,6 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog): QtCore.SIGNAL(u'stateChanged(int)'), self.onSlideTransitionCheckBoxChanged) - def saveAs(self): - self.ThemeNameEdit.setEnabled(True) - self.SaveAsButton.setEnabled(False) - self.ThemeNameEdit.setText(u'') - self.ThemeNameEdit.setFocus() - def accept(self): new_theme = ThemeXML() theme_name = unicode(self.ThemeNameEdit.text()) @@ -206,7 +200,7 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog): save_from, save_to) is not False: return QtGui.QDialog.accept(self) - def loadTheme(self, theme, newTheme=False): + def loadTheme(self, theme): log.debug(u'LoadTheme %s', theme) self.theme = theme # Stop the initial screen setup generating 1 preview per field! @@ -214,12 +208,6 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog): self.paintUi(self.theme) self.allowPreview = True self.previewTheme() - self.ThemeNameEdit.setEnabled(True) - self.SaveAsButton.setEnabled(False) - if not newTheme: - self.ThemeNameEdit.setEnabled(False) - self.SaveAsButton.setEnabled(True) - def onImageToolButtonClicked(self): images_filter = get_images_filter() diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 43f214690..46b4d0c50 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -173,7 +173,7 @@ class ThemeManager(QtGui.QWidget): editing form for the user to make their customisations. """ theme = self.createThemeFromXml(self.baseTheme(), self.path) - self.amendThemeForm.loadTheme(theme, True) + self.amendThemeForm.loadTheme(theme) self.saveThemeName = u'' self.amendThemeForm.exec_() From 0bd6d297c75e221bce437153c1e8fdb018a18f9b Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 11 Jul 2010 06:40:56 +0100 Subject: [PATCH 002/108] Add new renderer code --- openlp/core/lib/__init__.py | 5 ++ openlp/core/lib/renderer.py | 35 ++++++++++++ openlp/core/ui/maindisplay.py | 34 ++++++------ resources/Fedora/191/OpenLP.spec | 91 ++++++++++++++++++++++++++++++++ 4 files changed, 150 insertions(+), 15 deletions(-) create mode 100644 resources/Fedora/191/OpenLP.spec diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index 4718e289e..f3c9c4494 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -178,6 +178,11 @@ def resize_image(image, width, height): QtCore.Qt.SmoothTransformation) realw = preview.width() realh = preview.height() + #Only resize if different size + print realw, realh, width, height + if realw == width and realh == height: + return image + print "different" # and move it to the centre of the preview space new_image = QtGui.QImage(width, height, QtGui.QImage.Format_ARGB32_Premultiplied) diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index 04c854afa..ece02031a 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -145,6 +145,41 @@ class Renderer(object): for line in lines: text.append(line) split_text = self.pre_render_text(text) + + doc = QtGui.QTextDocument() + doc.setPageSize(QtCore.QSizeF(self._rect.width(), self._rect.height())) + df = doc.defaultFont() + df.setPixelSize(self._theme.font_main_proportion) + df.setFamily(self._theme.font_main_name) + main_weight = 50 + if self._theme.font_main_weight == u'Bold': + main_weight = 75 + df.setWeight(main_weight) + doc.setDefaultFont(df) + myCursor = QtGui.QTextCursor(doc) + layout = doc.documentLayout() + formatted = [] + if self._theme.display_horizontalAlign == 2: + shell = "

%s

" + elif self._theme.display_horizontalAlign == 1: + shell = "

%s

" + else: + shell = "

%s

" + temp_text = u'' + old_html_text = u'' + for line in text: + #do we need a
here? + temp_text = temp_text + line + html_text = shell % temp_text + doc.setHtml(html_text) + if layout.pageCount() != 1: + formatted.append(old_html_text) + temp_text = line + old_html_text = temp_text + formatted.append(old_html_text) + for f in formatted: + print "f", f + print "st", split_text log.debug(u'format_slide - End') return split_text diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index b0ef8eaf4..575038f77 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -79,10 +79,28 @@ class DisplayManager(QtGui.QWidget): QtCore.SIGNAL(u'videodisplay_start'), self.onStartVideo) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'videodisplay_stop'), self.onStopVideo) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'config_updated'), self.setup) def setup(self): + log.debug(u'mainDisplay - setup') self.videoDisplay.setup() self.mainDisplay.setup() + #Build the initial frame. + self.initialFrame = QtGui.QImage( + self.screens.current[u'size'].width(), + self.screens.current[u'size'].height(), + QtGui.QImage.Format_ARGB32_Premultiplied) + print self.screens.current + splash_image = QtGui.QImage(u':/graphics/openlp-splash-screen.png') + painter_image = QtGui.QPainter() + painter_image.begin(self.initialFrame) + painter_image.fillRect(self.initialFrame.rect(), QtCore.Qt.white) + painter_image.drawImage( + (self.screens.current[u'size'].width() - splash_image.width()) / 2, + (self.screens.current[u'size'].height() - splash_image.height()) / 2, + splash_image) + self.mainDisplay.displayImage(self.initialFrame) def hideDisplay(self, message): """ @@ -252,19 +270,6 @@ class MainDisplay(DisplayWidget): self.webView.setGeometry(0, 0, self.size().width(), self.size().height()) #Build a custom splash screen - self.initialFrame = QtGui.QImage( - self.screen[u'size'].width(), - self.screen[u'size'].height(), - QtGui.QImage.Format_ARGB32_Premultiplied) - splash_image = QtGui.QImage(u':/graphics/openlp-splash-screen.png') - painter_image = QtGui.QPainter() - painter_image.begin(self.initialFrame) - painter_image.fillRect(self.initialFrame.rect(), QtCore.Qt.white) - painter_image.drawImage( - (self.screen[u'size'].width() - splash_image.width()) / 2, - (self.screen[u'size'].height() - splash_image.height()) / 2, - splash_image) - self.displayImage(self.initialFrame) self.repaint() #Build a Black screen painter = QtGui.QPainter() @@ -498,8 +503,7 @@ class VideoDisplay(Phonon.VideoWidget): QtCore.SIGNAL(u'videodisplay_pause'), self.onMediaPause) # QtCore.QObject.connect(Receiver.get_receiver(), # QtCore.SIGNAL(u'videodisplay_background'), self.onMediaBackground) - QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'config_updated'), self.setup) + QtCore.QObject.connect(self.mediaObject, QtCore.SIGNAL(u'finished()'), self.onMediaStop) self.setVisible(False) diff --git a/resources/Fedora/191/OpenLP.spec b/resources/Fedora/191/OpenLP.spec new file mode 100644 index 000000000..7e9ccc1cc --- /dev/null +++ b/resources/Fedora/191/OpenLP.spec @@ -0,0 +1,91 @@ +%{!?python_sitelib:%global python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} + +Summary: Open source Church presentation and lyrics projection application +Name: OpenLP +Version: 1.9.1.1 +Release: 1%{?dist} +Source0: http://downloads.sourceforge.net/openlp/openlp/%{version}/%{name}-%{version}.tar.gz +License: GPLv2 +Group: Applications/Multimedia +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +BuildArch: noarch + +URL: http://openlp.org/ + +BuildRequires: desktop-file-utils +BuildRequires: python2-devel +BuildRequires: python-setuptools + +Requires: PyQt4 +Requires: phonon +Requires: python-BeautifulSoup +Requires: python-chardet +Requires: python-lxml +Requires: python-sqlalchemy +Requires: hicolor-icon-theme + +%description +OpenLP is a church presentation software, for lyrics projection software, +used to display slides of Songs, Bible verses, videos, images, and +presentations (if OpenOffice.org is installed) using a computer and projector. + +%prep +%setup -q + +%build +python setup.py build + +%install +rm -rf %{buildroot} +python setup.py install --skip-build -O1 --root %{buildroot} + +install -m644 -p -D resources/images/openlp-logo-16x16.png \ + %{buildroot}%{_datadir}/icons/hicolor/16x16/apps/openlp.png +install -m644 -p -D resources/images/openlp-logo-32x32.png \ + %{buildroot}%{_datadir}/icons/hicolor/32x32/apps/openlp.png +install -m644 -p -D resources/images/openlp-logo-48x48.png \ + %{buildroot}%{_datadir}/icons/hicolor/48x48/apps/openlp.png +install -m644 -p -D resources/images/openlp-logo.svg \ + %{buildroot}%{_datadir}/icons/hicolor/scalable/apps/openlp.svg + +desktop-file-install \ + --dir %{buildroot}/%{_datadir}/applications \ + resources/openlp.desktop + +mv %{buildroot}%{_bindir}/bible-1to2-converter.py \ + %{buildroot}%{_bindir}/bible-1to2-converter +mv %{buildroot}%{_bindir}/openlp-1to2-converter.py \ + %{buildroot}%{_bindir}/openlp-1to2-converter +mv %{buildroot}%{_bindir}/openlp-remoteclient.py \ + %{buildroot}%{_bindir}/openlp-remoteclient +mv %{buildroot}%{_bindir}/openlp.pyw %{buildroot}%{_bindir}/openlp + + +%post +touch --no-create %{_datadir}/icons/hicolor ||: +gtk-update-icon-cache -q %{_datadir}/icons/hicolor 2> /dev/null ||: + +%postun +touch --no-create %{_datadir}/icons/hicolor ||: +gtk-update-icon-cache -q %{_datadir}/icons/hicolor 2> /dev/null ||: + + +%clean +rm -rf %{buildroot} + +%files +%defattr(-,root,root) +%doc copyright.txt LICENSE +%{_bindir}/bible-1to2-converter +%{_bindir}/openlp-1to2-converter +%{_bindir}/openlp-remoteclient +%{_bindir}/openlp +%{_datadir}/applications/openlp.desktop +%{_datadir}/icons/hicolor/*/apps/openlp.* +%{python_sitelib}/openlp/ +%{python_sitelib}/OpenLP-%{version}*.egg-info +%doc documentation/*.txt + +%changelog +* Sun Mar 28 2010 Tim Bentley 1.9.1.1 +- Initial build version - Alpha 1 Release From 02c0fe9e896838600c9352b0a4844bb829a7b036 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 11 Jul 2010 08:45:49 +0100 Subject: [PATCH 003/108] Renderer replacement started --- openlp/core/lib/__init__.py | 44 +- openlp/core/lib/renderer.py | 18 +- openlp/core/ui/__init__.py | 2 - openlp/core/ui/maindisplay.py | 1028 +++++++++++++++++++-------------- 4 files changed, 637 insertions(+), 455 deletions(-) diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index f3c9c4494..088ac6e7a 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -165,12 +165,51 @@ def context_menu_separator(base): action.setSeparator(True) return action -def resize_image(image, width, height): +def resize_image_for_web(image, width, height, background=QtCore.Qt.black): + """ + Resize an image to fit on the current screen for the web and retuns + it as a byte stream. + + ``image`` + The image to resize. + ``width`` + The new image width. + ``height`` + The new image height. + ``background `` + The background colour defaults to black. + """ + new_image = resize_image(image, width, height, background) + return image_to_byte(image) + +def image_to_byte(image): + """ + Resize an image to fit on the current screen for the web and retuns + it as a byte stream. + + ``image`` + The image to converted. + """ + byte_array = QtCore.QByteArray() + buffer = QtCore.QBuffer(byte_array) #// use buffer to store pixmap into byteArray + buffer.open(QtCore.QIODevice.WriteOnly) + pixmap = QtGui.QPixmap(image) + pixmap.save(buffer, "PNG") + #convert to base64 encoding so does not get missed! + return byte_array + +def resize_image(image, width, height, background=QtCore.Qt.black): """ Resize an image to fit on the current screen. ``image`` The image to resize. + ``width`` + The new image width. + ``height`` + The new image height. + ``background `` + The background colour defaults to black. """ preview = QtGui.QImage(image) if not preview.isNull(): @@ -186,7 +225,7 @@ def resize_image(image, width, height): # and move it to the centre of the preview space new_image = QtGui.QImage(width, height, QtGui.QImage.Format_ARGB32_Premultiplied) - new_image.fill(QtCore.Qt.black) + new_image.fill(background) painter = QtGui.QPainter(new_image) painter.drawImage((width - realw) / 2, (height - realh) / 2, preview) return new_image @@ -215,6 +254,7 @@ from settingstab import SettingsTab from serviceitem import ServiceItem from serviceitem import ServiceItemType from serviceitem import ItemCapabilities +from htmlbuilder import build_html from toolbar import OpenLPToolbar from dockwidget import OpenLPDockWidget from theme import ThemeLevel, ThemeXML diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index ece02031a..ab4ce3d74 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -167,21 +167,25 @@ class Renderer(object): shell = "

%s

" temp_text = u'' old_html_text = u'' + page = [] for line in text: - #do we need a
here? - temp_text = temp_text + line + # mark line ends + temp_text = temp_text + line + u'
' html_text = shell % temp_text doc.setHtml(html_text) + #Text too long so gone to next mage if layout.pageCount() != 1: - formatted.append(old_html_text) + page.append(shell % old_html_text) + formatted.append(page) temp_text = line old_html_text = temp_text - formatted.append(old_html_text) - for f in formatted: - print "f", f + page.append(shell % old_html_text) + formatted.append(page) + print "ft", formatted print "st", split_text log.debug(u'format_slide - End') - return split_text + #return split_text + return formatted def pre_render_text(self, text): metrics = QtGui.QFontMetrics(self.main_font) diff --git a/openlp/core/ui/__init__.py b/openlp/core/ui/__init__.py index e93108da7..c4955daff 100644 --- a/openlp/core/ui/__init__.py +++ b/openlp/core/ui/__init__.py @@ -40,8 +40,6 @@ 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 diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 575038f77..9284b2d49 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -30,7 +30,7 @@ import time from PyQt4 import QtCore, QtGui, QtWebKit from PyQt4.phonon import Phonon -from openlp.core.lib import Receiver, resize_image +from openlp.core.lib import Receiver, resize_image, image_to_byte, build_html from openlp.core.ui import HideMode log = logging.getLogger(__name__) @@ -68,9 +68,9 @@ class DisplayManager(QtGui.QWidget): def __init__(self, screens): QtGui.QWidget.__init__(self) self.screens = screens - self.videoDisplay = VideoDisplay(self, screens) + #self.videoDisplay = VideoDisplay(self, screens) self.audioPlayer = AudioPlayer(self) - self.mainDisplay = MainDisplay(self, screens) + self.mainDisplay = WebViewer(self, screens) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'maindisplay_hide'), self.hideDisplay) QtCore.QObject.connect(Receiver.get_receiver(), @@ -82,9 +82,10 @@ class DisplayManager(QtGui.QWidget): QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_updated'), self.setup) + def setup(self): log.debug(u'mainDisplay - setup') - self.videoDisplay.setup() + #self.videoDisplay.setup() self.mainDisplay.setup() #Build the initial frame. self.initialFrame = QtGui.QImage( @@ -100,20 +101,19 @@ class DisplayManager(QtGui.QWidget): (self.screens.current[u'size'].width() - splash_image.width()) / 2, (self.screens.current[u'size'].height() - splash_image.height()) / 2, splash_image) - self.mainDisplay.displayImage(self.initialFrame) + self.mainDisplay.newDisplay(image_to_byte(QtGui.QPixmap.fromImage(self.initialFrame)), None, None) + self.mainDisplay.show() def hideDisplay(self, message): """ Hide the output displays """ - self.videoDisplay.mediaHide(message) self.mainDisplay.hideDisplay(message) def showDisplay(self, message): """ Hide the output displays """ - self.videoDisplay.mediaShow(message) self.mainDisplay.showDisplay(message) def addAlert(self, alertMessage, location): @@ -144,498 +144,638 @@ class DisplayManager(QtGui.QWidget): """ Handles the Starting of a Video and Display Management """ - self.videoDisplay.setVisible(True) self.mainDisplay.setVisible(False) - self.videoDisplay.onMediaQueue(item) def onStopVideo(self): """ Handles the Stopping of a Video and Display Management """ self.mainDisplay.setVisible(True) - self.videoDisplay.setVisible(False) - self.videoDisplay.onMediaStop() def close(self): """ Handles the closure of the displays """ - self.videoDisplay.close() - self.audioPlayer.close() - self.mainDisplay.close() + self.mainDisplay.close() class DisplayWidget(QtGui.QGraphicsView): """ Customised version of QTableWidget which can respond to keyboard events. """ - log.info(u'MainDisplay loaded') + log.info(u'Display Widget loaded') - def __init__(self, parent=None, name=None, primary=False): - QtGui.QWidget.__init__(self, None) + def __init__(self, parent=None, name=None): + QtGui.QGraphicsView.__init__(self) self.parent = parent - self.primary = primary - self.hotkey_map = { - QtCore.Qt.Key_Return: 'servicemanager_next_item', - QtCore.Qt.Key_Space: 'slidecontroller_live_next_noloop', - QtCore.Qt.Key_Enter: 'slidecontroller_live_next_noloop', - QtCore.Qt.Key_0: 'servicemanager_next_item', - QtCore.Qt.Key_Backspace: 'slidecontroller_live_previous_noloop'} def keyPressEvent(self, event): - if isinstance(event, QtGui.QKeyEvent): + if type(event) == QtGui.QKeyEvent: #here accept the event and do something - if event.key() == QtCore.Qt.Key_Up: - Receiver.send_message(u'slidecontroller_live_previous') - event.accept() - elif event.key() == QtCore.Qt.Key_Down: - Receiver.send_message(u'slidecontroller_live_next') - event.accept() - elif event.key() == QtCore.Qt.Key_PageUp: - Receiver.send_message(u'slidecontroller_live_first') - event.accept() - elif event.key() == QtCore.Qt.Key_PageDown: - Receiver.send_message(u'slidecontroller_live_last') - event.accept() - elif event.key() in self.hotkey_map: - Receiver.send_message(self.hotkey_map[event.key()]) + if event.key() == QtCore.Qt.Key_Down: + print "down" + self.next() event.accept() elif event.key() == QtCore.Qt.Key_Escape: - self.resetDisplay() + print "esc" + self.close() event.accept() - event.ignore() + elif event.key() == QtCore.Qt.Key_V: + print "v" + self.video() + event.accept() + elif event.key() == QtCore.Qt.Key_I: + print "I" + self.image() + event.accept() + elif event.key() == QtCore.Qt.Key_P: + print "p" + self.preview() + event.accept() + elif event.key() == QtCore.Qt.Key_A: + print "a" + self.alert() + event.accept() + elif event.key() == QtCore.Qt.Key_S: + print "s" + self.shadow() + event.accept() + else: + event.ignore() else: event.ignore() - def resetDisplay(self): - log.debug(u'resetDisplay') - Receiver.send_message(u'slidecontroller_live_stop_loop') - if self.primary: - self.setVisible(False) - else: - self.setVisible(True) - -class MainDisplay(DisplayWidget): - """ - This is the form that is used to display things on the projector. - """ - log.info(u'MainDisplay Loaded') +class WebViewer(DisplayWidget): def __init__(self, parent, screens): - """ - The constructor for the display form. + DisplayWidget.__init__(self, parent=None) + self.screen = screens + self.setupSelf() + self.currimage = False +# self.byteArray = QtCore.QByteArray() +# buffer = QtCore.QBuffer(self.byteArray) #// use buffer to store pixmap into byteArray +# buffer.open(QtCore.QIODevice.WriteOnly) +# pixmap = QtGui.QPixmap("/home/timali/Pictures/IMG_0726.jpg") +# pixmap.save(buffer, "PNG") +# self.byteArray2 = QtCore.QByteArray() +# buffer = QtCore.QBuffer(self.byteArray) #// use buffer to store pixmap into byteArray +# buffer.open(QtCore.QIODevice.WriteOnly) +# pixmap = QtGui.QPixmap("file:///home/timali/Pictures/out.png") +# pixmap.save(buffer, "PNG") + self.setup() +# self.image1 = "file:///home/timali/Pictures/IMG_0726.jpg" +# self.image2 = "file:///home/timali/Pictures/out.png" + self.currvideo = False + self.video1 = "c:\\users\\jonathan\\Desktop\\Wildlife.wmv" + self.video2 = "c:\\users\\jonathan\\Desktop\\movie.ogg" + self.currslide = False + self.slide1 = "[1:1] In the beginning God created the heavens and the earth.

[1:2] Now the earth was formless and empty, darkness was over the surface of the deep, and the Spirit of God was hovering over the waters.

[1:3] And God said, \"Let there be light,\" and there was light.

[1:4] God saw that the light was good, and he separated the light from the darkness.

" + self.slide2 = "

This is the chorus
Blah Blah Blah
Blah Blah Blah
Blah Blah Blah
Blah Blah Blah
Blah Blah Blah" + self.alerttext = "

Red Alert! Raise Shields!

" - ``parent`` - The parent widget. + def next(self): + print "next" + if self.currslide: + print "2" + self.frame.evaluateJavaScript("startfade('" + self.slide2 + "')") + #self.frame.findFirstElement('div#lyrics').setInnerXml(self.slide2) + else: + print "1" + self.frame.evaluateJavaScript("startfade('" + self.slide1 + "')") + #self.frame.findFirstElement('div#lyrics').setInnerXml(self.slide1) + self.currslide = not self.currslide - ``screens`` - The list of screens. - """ - log.debug(u'Initialisation started') - DisplayWidget.__init__(self, parent, primary=True) - self.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.FramelessWindowHint) - self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) - self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) - # WA_TranslucentBackground is not available in QT4.4 - try: - self.setAttribute(QtCore.Qt.WA_TranslucentBackground) - except AttributeError: - pass - self.screens = screens - self.setupScene() - self.setupVideo() - self.setupImage() - self.setupText() - self.setupAlert() - self.setupBlank() - self.blankFrame = None - self.frame = None - #Hide desktop for now until we know where to put it - #and what size it should be. - self.setVisible(False) + def text(self, slide): + self.frame.findFirstElement('div#lyrics').setInnerXml(self.slides(slide)) + + def alert(self): + self.frame.findFirstElement('div#alert').setInnerXml(self.alerttext) + + def image(self, byteImage): + self.frame.evaluateJavaScript( + "document.getElementById('video').style.visibility = 'hidden'") + self.frame.evaluateJavaScript( + "document.getElementById('image').style.visibility = 'visible'") + if self.currimage: + self.frame.findFirstElement('img').setAttribute( + 'src', unicode('data:image/png;base64,%s' % byteImage.toBase64())) + self.currimage = not self.currimage + + def video(self, videoPath, noSound=False): + if self.currimage: + self.frame.findFirstElement('video').setAttribute('src', videoPath) + self.frame.evaluateJavaScript( + "document.getElementById('video').style.visibility = 'visible'") + self.frame.evaluateJavaScript( + "document.getElementById('image').style.visibility = 'hidden'") + self.frame.evaluateJavaScript("document.getElementById('video').play()") + self.currimage = not self.currimage + + def setupSelf(self): + self.setWindowTitle(u'OpenLP Display') + self.setWindowFlags(QtCore.Qt.FramelessWindowHint | + QtCore.Qt.WindowStaysOnTopHint) + self.setGeometry(1440, 0, self.screen.current[u'size'].width(), self.screen.current[u'size'].height()) def setup(self): - """ - Sets up the screen on a particular screen. - """ - 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.scene.setSceneRect(0, 0, self.size().width(), - self.size().height()) - self.webView.setGeometry(0, 0, self.size().width(), - self.size().height()) - #Build a custom splash screen - self.repaint() - #Build a Black screen - painter = QtGui.QPainter() - self.blankFrame = QtGui.QImage( - self.screen[u'size'].width(), - self.screen[u'size'].height(), - QtGui.QImage.Format_ARGB32_Premultiplied) - painter.begin(self.blankFrame) - 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.displayText.setPixmap(self.transparent) - #self.frameView(self.transparent) - # To display or not to display? - if not self.screen[u'primary']: - self.setVisible(True) - self.primary = False - else: - self.setVisible(False) - self.primary = True - - def setupScene(self): - self.scene = QtGui.QGraphicsScene(self) - self.scene.setSceneRect(0, 0, self.size().width(), self.size().height()) - self.setScene(self.scene) - - def setupVideo(self): - self.webView = QtWebKit.QWebView() + self.webView = QtWebKit.QWebView(self) + self.webView.setGeometry(0, 0, self.screen.current[u'size'].width(), self.screen.current[u'size'].height()) self.page = self.webView.page() - self.videoDisplay = self.page.mainFrame() - self.videoDisplay.setScrollBarPolicy(QtCore.Qt.Vertical, +# html = build_html(None, self.screen, None, self.byteArray) +# self.webView.setHtml(html) + self.frame = self.page.mainFrame() + self.frame.setScrollBarPolicy(QtCore.Qt.Vertical, QtCore.Qt.ScrollBarAlwaysOff) - self.videoDisplay.setScrollBarPolicy(QtCore.Qt.Horizontal, + self.frame.setScrollBarPolicy(QtCore.Qt.Horizontal, QtCore.Qt.ScrollBarAlwaysOff) - self.proxy = QtGui.QGraphicsProxyWidget() - self.proxy.setWidget(self.webView) - self.proxy.setWindowFlags(QtCore.Qt.Window | - QtCore.Qt.FramelessWindowHint) - self.proxy.setZValue(1) - self.scene.addItem(self.proxy) - def setupImage(self): - self.imageDisplay = QtGui.QGraphicsPixmapItem() - self.imageDisplay.setZValue(2) - self.scene.addItem(self.imageDisplay) + def preview(self): + self.setVisible(False) + preview = QtGui.QImage(QtCore.QSize(640, 480), QtGui.QImage.Format_ARGB32_Premultiplied) + painter = QtGui.QPainter(preview) + painter.setRenderHint(QtGui.QPainter.Antialiasing) + self.frame.render(painter) + painter.end() + preview.save("temp.png", "png") + return preview - def setupText(self): - #self.displayText = QtGui.QGraphicsTextItem() - self.displayText = QtGui.QGraphicsPixmapItem() - #self.displayText.setPos(0,0) - #self.displayText.setTextWidth(self.size().width()) - self.displayText.setZValue(4) - self.scene.addItem(self.displayText) + def newDisplay(self, image, text, video=None): + if not video: + html = build_html(None, self.screen.current, None, image) + self.webView.setHtml(html) - def setupAlert(self): - self.alertText = QtGui.QGraphicsTextItem() - self.alertText.setTextWidth(self.size().width()) - self.alertText.setZValue(8) - self.scene.addItem(self.alertText) - - def setupBlank(self): - self.displayBlank = QtGui.QGraphicsPixmapItem() - self.displayBlank.setZValue(10) - self.scene.addItem(self.displayBlank) - -# def hideDisplayForVideo(self): +#class DisplayWidget(QtGui.QGraphicsView): +# """ +# Customised version of QTableWidget which can respond to keyboard +# events. +# """ +# log.info(u'MainDisplay loaded') +# +# def __init__(self, parent=None, name=None, primary=False): +# QtGui.QWidget.__init__(self, None) +# self.parent = parent +# self.primary = primary +# self.hotkey_map = { +# QtCore.Qt.Key_Return: 'servicemanager_next_item', +# QtCore.Qt.Key_Space: 'slidecontroller_live_next_noloop', +# QtCore.Qt.Key_Enter: 'slidecontroller_live_next_noloop', +# QtCore.Qt.Key_0: 'servicemanager_next_item', +# QtCore.Qt.Key_Backspace: 'slidecontroller_live_previous_noloop'} +# +# def keyPressEvent(self, event): +# if isinstance(event, QtGui.QKeyEvent): +# #here accept the event and do something +# if event.key() == QtCore.Qt.Key_Up: +# Receiver.send_message(u'slidecontroller_live_previous') +# event.accept() +# elif event.key() == QtCore.Qt.Key_Down: +# Receiver.send_message(u'slidecontroller_live_next') +# event.accept() +# elif event.key() == QtCore.Qt.Key_PageUp: +# Receiver.send_message(u'slidecontroller_live_first') +# event.accept() +# elif event.key() == QtCore.Qt.Key_PageDown: +# Receiver.send_message(u'slidecontroller_live_last') +# event.accept() +# elif event.key() in self.hotkey_map: +# Receiver.send_message(self.hotkey_map[event.key()]) +# event.accept() +# elif event.key() == QtCore.Qt.Key_Escape: +# self.resetDisplay() +# event.accept() +# event.ignore() +# else: +# event.ignore() +# +# def resetDisplay(self): +# log.debug(u'resetDisplay') +# Receiver.send_message(u'slidecontroller_live_stop_loop') +# if self.primary: +# self.setVisible(False) +# else: +# self.setVisible(True) +# +#class MainDisplay(DisplayWidget): +# """ +# This is the form that is used to display things on the projector. +# """ +# log.info(u'MainDisplay Loaded') +# +# def __init__(self, parent, screens): # """ -# Hides the main display if for the video to be played +# The constructor for the display form. +# +# ``parent`` +# The parent widget. +# +# ``screens`` +# The list of screens. # """ -# self.hideDisplay(HideMode.Screen) - - def hideDisplay(self, mode=HideMode.Screen): - """ - Hide the display by making all layers transparent - Store the images so they can be replaced when required - """ - log.debug(u'hideDisplay mode = %d', mode) - #self.displayText.setPixmap(self.transparent) - if mode == HideMode.Screen: - #self.display_image.setPixmap(self.transparent) - self.setVisible(False) - elif mode == HideMode.Blank: - self.displayBlank.setPixmap( - QtGui.QPixmap.fromImage(self.blankFrame)) - else: - if self.parent.renderManager.renderer.bg_frame: - self.displayBlank.setPixmap(QtGui.QPixmap.fromImage( - self.parent.renderManager.renderer.bg_frame)) - else: - self.displayBlank.setPixmap( - QtGui.QPixmap.fromImage(self.blankFrame)) - - def showDisplay(self, message=u''): - """ - Show the stored layers so the screen reappears as it was - originally. - Make the stored images None to release memory. - """ - log.debug(u'showDisplay') - self.displayBlank.setPixmap(self.transparent) - #Trigger actions when display is active again - Receiver.send_message(u'maindisplay_active') - - def addImageWithText(self, frame): - log.debug(u'addImageWithText') - frame = resize_image( - frame, self.screen[u'size'].width(), self.screen[u'size'].height()) - self.imageDisplay.setPixmap(QtGui.QPixmap.fromImage(frame)) - self.videoDisplay.setHtml(u'') - - def addAlert(self, message, location): - """ - Places the Alert text on the display at the correct location - ``message`` - Text to be displayed - ``location`` - Where on the screen the text should be. From the AlertTab - Combo box. - """ - log.debug(u'addAlertImage') - if location == 0: - self.alertText.setPos(0, 0) - elif location == 1: - self.alertText.setPos(0, self.size().height() / 2) - else: - self.alertText.setPos(0, self.size().height() - 76) - self.alertText.setHtml(message) - - def displayImage(self, frame): - """ - Places the Image passed on the display screen - ``frame`` - The image to be displayed - """ - log.debug(u'adddisplayImage') - if isinstance(frame, QtGui.QImage): - self.imageDisplay.setPixmap(QtGui.QPixmap.fromImage(frame)) - else: - self.imageDisplay.setPixmap(frame) - self.videoDisplay.setHtml(u'') - - def displayVideo(self, path): - """ - Places the Video passed on the display screen - ``path`` - The path to the image to be displayed - """ - log.debug(u'adddisplayVideo') - self.displayImage(self.transparent) - self.videoDisplay.setHtml(HTMLVIDEO % - (path, self.screen[u'size'].width(), - self.screen[u'size'].height())) - - def frameView(self, frame, transition=False): - """ - Called from a slide controller to display a frame - if the alert is in progress the alert is added on top - ``frame`` - Image frame to be rendered - ``transition`` - Are transitions required. - """ - log.debug(u'frameView') - if transition: - if self.frame is not None: - self.displayText.setPixmap( - QtGui.QPixmap.fromImage(self.frame)) - self.repaint() - Receiver.send_message(u'openlp_process_events') - time.sleep(0.1) - self.frame = None - if frame[u'trans'] is not None: - self.displayText.setPixmap( - QtGui.QPixmap.fromImage(frame[u'trans'])) - self.repaint() - Receiver.send_message(u'openlp_process_events') - time.sleep(0.1) - self.frame = frame[u'trans'] - self.displayText.setPixmap( - QtGui.QPixmap.fromImage(frame[u'main'])) - else: - if isinstance(frame, QtGui.QPixmap): - self.displayText.setPixmap(frame) - else: - self.displayText.setPixmap(QtGui.QPixmap.fromImage(frame)) - if not self.isVisible() and self.screens.display: - self.setVisible(True) - -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 Initialisation started') - Phonon.VideoWidget.__init__(self) - self.setWindowTitle(u'OpenLP Video Display') - self.parent = parent - self.screens = screens - self.hidden = False - self.message = None - self.mediaActive = False - self.mediaObject = Phonon.MediaObject() - self.setAspectRatio(aspect) - self.audioObject = Phonon.AudioOutput(Phonon.VideoCategory) - Phonon.createPath(self.mediaObject, self) - Phonon.createPath(self.mediaObject, self.audioObject) - flags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Dialog -## # WindowsStaysOnBottomHint is not available in QT4.4 +# log.debug(u'Initialisation started') +# DisplayWidget.__init__(self, parent, primary=True) +# self.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.FramelessWindowHint) +# self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) +# self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) +# # WA_TranslucentBackground is not available in QT4.4 # try: -# flags = flags | QtCore.Qt.WindowStaysOnBottomHint +# self.setAttribute(QtCore.Qt.WA_TranslucentBackground) # except AttributeError: # pass - self.setWindowFlags(flags) - QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'videodisplay_play'), self.onMediaPlay) - QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'videodisplay_pause'), self.onMediaPause) -# QtCore.QObject.connect(Receiver.get_receiver(), -# QtCore.SIGNAL(u'videodisplay_background'), self.onMediaBackground) - - QtCore.QObject.connect(self.mediaObject, - QtCore.SIGNAL(u'finished()'), self.onMediaStop) - self.setVisible(False) - - def keyPressEvent(self, event): - if isinstance(event, QtGui.QKeyEvent): - #here accept the event and do something - if event.key() == QtCore.Qt.Key_Escape: - self.onMediaStop() - event.accept() - event.ignore() - else: - 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.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']: # and self.isVisible(): - #self.showFullScreen() - self.setVisible(False) - self.primary = False - else: - self.setVisible(False) - self.primary = True - - def closeEvent(self, event): - """ - Shutting down so clean up connections - """ - self.onMediaStop() - for path in self.outputPaths(): - path.disconnect() - -# def onMediaBackground(self, message=None): +# self.screens = screens +# self.setupScene() +# self.setupVideo() +# self.setupImage() +# self.setupText() +# self.setupAlert() +# self.setupBlank() +# self.blankFrame = None +# self.frame = None +# #Hide desktop for now until we know where to put it +# #and what size it should be. +# self.setVisible(False) +# +# def setup(self): # """ -# Play a video triggered from the video plugin with the -# file name passed in on the event. -# Also triggered from the Finish event so the video will loop -# if it is triggered from the plugin +# Sets up the screen on a particular screen. +# """ +# 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.scene.setSceneRect(0, 0, self.size().width(), +# self.size().height()) +# self.webView.setGeometry(0, 0, self.size().width(), +# self.size().height()) +# #Build a custom splash screen +# self.repaint() +# #Build a Black screen +# painter = QtGui.QPainter() +# self.blankFrame = QtGui.QImage( +# self.screen[u'size'].width(), +# self.screen[u'size'].height(), +# QtGui.QImage.Format_ARGB32_Premultiplied) +# painter.begin(self.blankFrame) +# 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.displayText.setPixmap(self.transparent) +# #self.frameView(self.transparent) +# # To display or not to display? +# if not self.screen[u'primary']: +# self.setVisible(True) +# self.primary = False +# else: +# self.setVisible(False) +# self.primary = True +# +# def setupScene(self): +# self.scene = QtGui.QGraphicsScene(self) +# self.scene.setSceneRect(0, 0, self.size().width(), self.size().height()) +# self.setScene(self.scene) +# +# def setupVideo(self): +# self.webView = QtWebKit.QWebView() +# self.page = self.webView.page() +# self.videoDisplay = self.page.mainFrame() +# self.videoDisplay.setScrollBarPolicy(QtCore.Qt.Vertical, +# QtCore.Qt.ScrollBarAlwaysOff) +# self.videoDisplay.setScrollBarPolicy(QtCore.Qt.Horizontal, +# QtCore.Qt.ScrollBarAlwaysOff) +# self.proxy = QtGui.QGraphicsProxyWidget() +# self.proxy.setWidget(self.webView) +# self.proxy.setWindowFlags(QtCore.Qt.Window | +# QtCore.Qt.FramelessWindowHint) +# self.proxy.setZValue(1) +# self.scene.addItem(self.proxy) +# +# def setupImage(self): +# self.imageDisplay = QtGui.QGraphicsPixmapItem() +# self.imageDisplay.setZValue(2) +# self.scene.addItem(self.imageDisplay) +# +# def setupText(self): +# #self.displayText = QtGui.QGraphicsTextItem() +# self.displayText = QtGui.QGraphicsPixmapItem() +# #self.displayText.setPos(0,0) +# #self.displayText.setTextWidth(self.size().width()) +# self.displayText.setZValue(4) +# self.scene.addItem(self.displayText) +# +# def setupAlert(self): +# self.alertText = QtGui.QGraphicsTextItem() +# self.alertText.setTextWidth(self.size().width()) +# self.alertText.setZValue(8) +# self.scene.addItem(self.alertText) +# +# def setupBlank(self): +# self.displayBlank = QtGui.QGraphicsPixmapItem() +# self.displayBlank.setZValue(10) +# self.scene.addItem(self.displayBlank) +# +## def hideDisplayForVideo(self): +## """ +## Hides the main display if for the video to be played +## """ +## self.hideDisplay(HideMode.Screen) +# +# def hideDisplay(self, mode=HideMode.Screen): +# """ +# Hide the display by making all layers transparent +# Store the images so they can be replaced when required +# """ +# log.debug(u'hideDisplay mode = %d', mode) +# #self.displayText.setPixmap(self.transparent) +# if mode == HideMode.Screen: +# #self.display_image.setPixmap(self.transparent) +# self.setVisible(False) +# elif mode == HideMode.Blank: +# self.displayBlank.setPixmap( +# QtGui.QPixmap.fromImage(self.blankFrame)) +# else: +# if self.parent.renderManager.renderer.bg_frame: +# self.displayBlank.setPixmap(QtGui.QPixmap.fromImage( +# self.parent.renderManager.renderer.bg_frame)) +# else: +# self.displayBlank.setPixmap( +# QtGui.QPixmap.fromImage(self.blankFrame)) +# +# def showDisplay(self, message=u''): +# """ +# Show the stored layers so the screen reappears as it was +# originally. +# Make the stored images None to release memory. +# """ +# log.debug(u'showDisplay') +# self.displayBlank.setPixmap(self.transparent) +# #Trigger actions when display is active again +# Receiver.send_message(u'maindisplay_active') +# +# def addImageWithText(self, frame): +# log.debug(u'addImageWithText') +# frame = resize_image( +# frame, self.screen[u'size'].width(), self.screen[u'size'].height()) +# self.imageDisplay.setPixmap(QtGui.QPixmap.fromImage(frame)) +# self.videoDisplay.setHtml(u'') +# +# def addAlert(self, message, location): +# """ +# Places the Alert text on the display at the correct location +# ``message`` +# Text to be displayed +# ``location`` +# Where on the screen the text should be. From the AlertTab +# Combo box. +# """ +# log.debug(u'addAlertImage') +# if location == 0: +# self.alertText.setPos(0, 0) +# elif location == 1: +# self.alertText.setPos(0, self.size().height() / 2) +# else: +# self.alertText.setPos(0, self.size().height() - 76) +# self.alertText.setHtml(message) +# +# def displayImage(self, frame): +# """ +# Places the Image passed on the display screen +# ``frame`` +# The image to be displayed +# """ +# log.debug(u'adddisplayImage') +# if isinstance(frame, QtGui.QImage): +# self.imageDisplay.setPixmap(QtGui.QPixmap.fromImage(frame)) +# else: +# self.imageDisplay.setPixmap(frame) +# self.videoDisplay.setHtml(u'') +# +# def displayVideo(self, path): +# """ +# Places the Video passed on the display screen +# ``path`` +# The path to the image to be displayed +# """ +# log.debug(u'adddisplayVideo') +# self.displayImage(self.transparent) +# self.videoDisplay.setHtml(HTMLVIDEO % +# (path, self.screen[u'size'].width(), +# self.screen[u'size'].height())) +# +# def frameView(self, frame, transition=False): +# """ +# Called from a slide controller to display a frame +# if the alert is in progress the alert is added on top +# ``frame`` +# Image frame to be rendered +# ``transition`` +# Are transitions required. +# """ +# log.debug(u'frameView') +# if transition: +# if self.frame is not None: +# self.displayText.setPixmap( +# QtGui.QPixmap.fromImage(self.frame)) +# self.repaint() +# Receiver.send_message(u'openlp_process_events') +# time.sleep(0.1) +# self.frame = None +# if frame[u'trans'] is not None: +# self.displayText.setPixmap( +# QtGui.QPixmap.fromImage(frame[u'trans'])) +# self.repaint() +# Receiver.send_message(u'openlp_process_events') +# time.sleep(0.1) +# self.frame = frame[u'trans'] +# self.displayText.setPixmap( +# QtGui.QPixmap.fromImage(frame[u'main'])) +# else: +# if isinstance(frame, QtGui.QPixmap): +# self.displayText.setPixmap(frame) +# else: +# self.displayText.setPixmap(QtGui.QPixmap.fromImage(frame)) +# if not self.isVisible() and self.screens.display: +# self.setVisible(True) +# +#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 Initialisation started') +# Phonon.VideoWidget.__init__(self) +# self.setWindowTitle(u'OpenLP Video Display') +# self.parent = parent +# self.screens = screens +# self.hidden = False +# self.message = None +# self.mediaActive = False +# self.mediaObject = Phonon.MediaObject() +# self.setAspectRatio(aspect) +# self.audioObject = Phonon.AudioOutput(Phonon.VideoCategory) +# Phonon.createPath(self.mediaObject, self) +# Phonon.createPath(self.mediaObject, self.audioObject) +# flags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Dialog +### # WindowsStaysOnBottomHint is not available in QT4.4 +## try: +## flags = flags | QtCore.Qt.WindowStaysOnBottomHint +## except AttributeError: +## pass +# self.setWindowFlags(flags) +# QtCore.QObject.connect(Receiver.get_receiver(), +# QtCore.SIGNAL(u'videodisplay_play'), self.onMediaPlay) +# QtCore.QObject.connect(Receiver.get_receiver(), +# QtCore.SIGNAL(u'videodisplay_pause'), self.onMediaPause) +## QtCore.QObject.connect(Receiver.get_receiver(), +## QtCore.SIGNAL(u'videodisplay_background'), self.onMediaBackground) +# +# QtCore.QObject.connect(self.mediaObject, +# QtCore.SIGNAL(u'finished()'), self.onMediaStop) +# self.setVisible(False) +# +# def keyPressEvent(self, event): +# if isinstance(event, QtGui.QKeyEvent): +# #here accept the event and do something +# if event.key() == QtCore.Qt.Key_Escape: +# self.onMediaStop() +# event.accept() +# event.ignore() +# else: +# 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.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']: # and self.isVisible(): +# #self.showFullScreen() +# self.setVisible(False) +# self.primary = False +# else: +# self.setVisible(False) +# self.primary = True +# +# def closeEvent(self, event): +# """ +# Shutting down so clean up connections +# """ +# self.onMediaStop() +# for path in self.outputPaths(): +# path.disconnect() +# +## def onMediaBackground(self, message=None): +## """ +## Play a video triggered from the video plugin with the +## file name passed in on the event. +## Also triggered from the Finish event so the video will loop +## if it is triggered from the plugin +## """ +## log.debug(u'VideoDisplay Queue new media message %s' % message) +## #If not file take the stored one +## if not message: +## message = self.message +## # still no file name then stop as it was a normal video stopping +## if message: +## self.mediaObject.setCurrentSource(Phonon.MediaSource(message)) +## self.message = message +## self._play() +# +# def onMediaQueue(self, message): +# """ +# Set up a video to play from the serviceitem. # """ # log.debug(u'VideoDisplay Queue new media message %s' % message) -# #If not file take the stored one -# if not message: -# message = self.message -# # still no file name then stop as it was a normal video stopping -# if message: -# self.mediaObject.setCurrentSource(Phonon.MediaSource(message)) -# self.message = message +# file = os.path.join(message.get_frame_path(), +# message.get_frame_title()) +# self.mediaObject.setCurrentSource(Phonon.MediaSource(file)) +# self.mediaActive = True +# self._play() +# +# def onMediaPlay(self): +# """ +# Respond to the Play button on the slide controller unless the display +# has been hidden by the slidecontroller +# """ +# if not self.hidden: +# log.debug(u'VideoDisplay Play the new media, Live ') # self._play() - - def onMediaQueue(self, message): - """ - Set up a video to play from the serviceitem. - """ - log.debug(u'VideoDisplay Queue new media message %s' % message) - file = os.path.join(message.get_frame_path(), - message.get_frame_title()) - self.mediaObject.setCurrentSource(Phonon.MediaSource(file)) - self.mediaActive = True - self._play() - - def onMediaPlay(self): - """ - Respond to the Play button on the slide controller unless the display - has been hidden by the slidecontroller - """ - if not self.hidden: - log.debug(u'VideoDisplay Play the new media, Live ') - self._play() - - def _play(self): - """ - We want to play the video so start it and display the screen - """ - log.debug(u'VideoDisplay _play called') - self.mediaObject.play() - self.setVisible(True) - - def onMediaPause(self): - """ - Pause the video and refresh the screen - """ - log.debug(u'VideoDisplay Media paused by user') - self.mediaObject.pause() - self.show() - - def onMediaStop(self): - """ - Stop the video and clean up - """ - log.debug(u'VideoDisplay Media stopped by user') - self.message = None - self.mediaActive = False - self.mediaObject.stop() - self.onMediaFinish() - - def onMediaFinish(self): - """ - Clean up the Object queue - """ - log.debug(u'VideoDisplay Reached end of media playlist') - self.mediaObject.clearQueue() - self.setVisible(False) - - def mediaHide(self, message=u''): - """ - Hide the video display - """ - self.mediaObject.pause() - self.hidden = True - self.setVisible(False) - - def mediaShow(self, message=''): - """ - Show the video display if it was already hidden - """ - if self.hidden: - self.hidden = False - if self.mediaActive: - self._play() +# +# def _play(self): +# """ +# We want to play the video so start it and display the screen +# """ +# log.debug(u'VideoDisplay _play called') +# self.mediaObject.play() +# self.setVisible(True) +# +# def onMediaPause(self): +# """ +# Pause the video and refresh the screen +# """ +# log.debug(u'VideoDisplay Media paused by user') +# self.mediaObject.pause() +# self.show() +# +# def onMediaStop(self): +# """ +# Stop the video and clean up +# """ +# log.debug(u'VideoDisplay Media stopped by user') +# self.message = None +# self.mediaActive = False +# self.mediaObject.stop() +# self.onMediaFinish() +# +# def onMediaFinish(self): +# """ +# Clean up the Object queue +# """ +# log.debug(u'VideoDisplay Reached end of media playlist') +# self.mediaObject.clearQueue() +# self.setVisible(False) +# +# def mediaHide(self, message=u''): +# """ +# Hide the video display +# """ +# self.mediaObject.pause() +# self.hidden = True +# self.setVisible(False) +# +# def mediaShow(self, message=''): +# """ +# Show the video display if it was already hidden +# """ +# if self.hidden: +# self.hidden = False +# if self.mediaActive: +# self._play() class AudioPlayer(QtCore.QObject): """ This Class will play audio only allowing components to work with a - soundtrack which does not take over the user interface. + soundtrack independent of the user interface. """ log.info(u'AudioPlayer Loaded') From 44ae86e82bcf1756178e0f6d2c9097e485325eb2 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 11 Jul 2010 11:58:36 +0100 Subject: [PATCH 004/108] Renderer replacement humm --- openlp/core/lib/__init__.py | 24 ++--- openlp/core/lib/htmlbuilder.py | 155 +++++++++++++++++++++++++++++++++ openlp/core/ui/maindisplay.py | 4 +- 3 files changed, 162 insertions(+), 21 deletions(-) create mode 100644 openlp/core/lib/htmlbuilder.py diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index 088ac6e7a..fa2161872 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -165,23 +165,6 @@ def context_menu_separator(base): action.setSeparator(True) return action -def resize_image_for_web(image, width, height, background=QtCore.Qt.black): - """ - Resize an image to fit on the current screen for the web and retuns - it as a byte stream. - - ``image`` - The image to resize. - ``width`` - The new image width. - ``height`` - The new image height. - ``background `` - The background colour defaults to black. - """ - new_image = resize_image(image, width, height, background) - return image_to_byte(image) - def image_to_byte(image): """ Resize an image to fit on the current screen for the web and retuns @@ -193,10 +176,13 @@ def image_to_byte(image): byte_array = QtCore.QByteArray() buffer = QtCore.QBuffer(byte_array) #// use buffer to store pixmap into byteArray buffer.open(QtCore.QIODevice.WriteOnly) - pixmap = QtGui.QPixmap(image) + if isinstance(image, QtGui.QImage): + pixmap = QtGui.QPixmap.fromImage(image) + else: + pixmap = QtGui.QPixmap(image) pixmap.save(buffer, "PNG") #convert to base64 encoding so does not get missed! - return byte_array + return byte_array.toBase64() def resize_image(image, width, height, background=QtCore.Qt.black): """ diff --git a/openlp/core/lib/htmlbuilder.py b/openlp/core/lib/htmlbuilder.py new file mode 100644 index 000000000..2111dbada --- /dev/null +++ b/openlp/core/lib/htmlbuilder.py @@ -0,0 +1,155 @@ +# -*- 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 openlp.core.lib import image_to_byte + +HTMLSRC = u""" + + +OpenLP Display + + + + +
+
+
+ +%s + + + """ +def build_html(theme, screen, alert, image): + width = screen[u'size'].width() + height = screen[u'size'].height() + aa = build_image_src(theme, width, height, alert, image) + html = HTMLSRC % (build_video(theme, width, height, alert), + build_image(theme, width, height, alert), + build_lyrics(theme, width, height, alert), + build_alert(theme, width, height, alert), + build_image(theme, width, height, alert)) + #build_image_src(theme, width, height, alert, image)) + print html + return html + +def build_video(theme, width, height, alert): + video = """ + #video { + position: absolute; + left: 0px; + top: 0px; + width: 640px + height: 480px; + z-index:1; + } + """ + return video + +def build_image(theme, width, height, alert): + image = """ + #image { + position: absolute; + left: 0px; + top: 0px; + width: %spx; + height: %spx; + z-index:2; + } + """ + return image % (width, height) + +def build_image_src(theme, width, height, alert, image): + # + image_src = """ + "; + """ + return unicode(image_src % unicode(image_to_byte(image))) + +def build_lyrics(theme, width, height, alert): + lyrics = """ + .lyrics { + position: absolute; + left: 0px; + top: 0px; + width: 640px; + height: 480px; + z-index:3; + text-shadow: 2px 2px 2px green; + font-size: 40px; + } + """ + return lyrics + +def build_alert(theme, width, height, alert): + alert = """ + #alert { + position: absolute; + left: 0px; + top: 70px; + width: %spx; + height: 10px; + z-index:4; + font-size: 50px; + } + #alert p { + background-color: red; + } + """ + return alert % (width) diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 9284b2d49..bbe6e43e5 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -30,7 +30,7 @@ import time from PyQt4 import QtCore, QtGui, QtWebKit from PyQt4.phonon import Phonon -from openlp.core.lib import Receiver, resize_image, image_to_byte, build_html +from openlp.core.lib import Receiver, resize_image, build_html from openlp.core.ui import HideMode log = logging.getLogger(__name__) @@ -101,7 +101,7 @@ class DisplayManager(QtGui.QWidget): (self.screens.current[u'size'].width() - splash_image.width()) / 2, (self.screens.current[u'size'].height() - splash_image.height()) / 2, splash_image) - self.mainDisplay.newDisplay(image_to_byte(QtGui.QPixmap.fromImage(self.initialFrame)), None, None) + self.mainDisplay.newDisplay(self.initialFrame, None, None) self.mainDisplay.show() def hideDisplay(self, message): From c46901cb8a3eb4fe2103b21135b8e9eee281d143 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 11 Jul 2010 12:38:09 +0100 Subject: [PATCH 005/108] Renderer replacement- screen fix --- openlp/core/lib/htmlbuilder.py | 3 +-- openlp/core/ui/maindisplay.py | 29 ++++++++++++----------------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/openlp/core/lib/htmlbuilder.py b/openlp/core/lib/htmlbuilder.py index 2111dbada..5361fe044 100644 --- a/openlp/core/lib/htmlbuilder.py +++ b/openlp/core/lib/htmlbuilder.py @@ -84,9 +84,8 @@ def build_html(theme, screen, alert, image): build_image(theme, width, height, alert), build_lyrics(theme, width, height, alert), build_alert(theme, width, height, alert), - build_image(theme, width, height, alert)) + build_image(theme, width, height, alert), aa) #build_image_src(theme, width, height, alert, image)) - print html return html def build_video(theme, width, height, alert): diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index bbe6e43e5..017d59280 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -68,7 +68,6 @@ class DisplayManager(QtGui.QWidget): def __init__(self, screens): QtGui.QWidget.__init__(self) self.screens = screens - #self.videoDisplay = VideoDisplay(self, screens) self.audioPlayer = AudioPlayer(self) self.mainDisplay = WebViewer(self, screens) QtCore.QObject.connect(Receiver.get_receiver(), @@ -82,11 +81,8 @@ class DisplayManager(QtGui.QWidget): QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_updated'), self.setup) - def setup(self): log.debug(u'mainDisplay - setup') - #self.videoDisplay.setup() - self.mainDisplay.setup() #Build the initial frame. self.initialFrame = QtGui.QImage( self.screens.current[u'size'].width(), @@ -101,6 +97,7 @@ class DisplayManager(QtGui.QWidget): (self.screens.current[u'size'].width() - splash_image.width()) / 2, (self.screens.current[u'size'].height() - splash_image.height()) / 2, splash_image) + self.mainDisplay.setup() self.mainDisplay.newDisplay(self.initialFrame, None, None) self.mainDisplay.show() @@ -210,8 +207,10 @@ class WebViewer(DisplayWidget): def __init__(self, parent, screens): DisplayWidget.__init__(self, parent=None) - self.screen = screens - self.setupSelf() + self.screens = screens + self.setWindowTitle(u'OpenLP Display') + self.setWindowFlags(QtCore.Qt.FramelessWindowHint | + QtCore.Qt.WindowStaysOnTopHint) self.currimage = False # self.byteArray = QtCore.QByteArray() # buffer = QtCore.QBuffer(self.byteArray) #// use buffer to store pixmap into byteArray @@ -223,7 +222,6 @@ class WebViewer(DisplayWidget): # buffer.open(QtCore.QIODevice.WriteOnly) # pixmap = QtGui.QPixmap("file:///home/timali/Pictures/out.png") # pixmap.save(buffer, "PNG") - self.setup() # self.image1 = "file:///home/timali/Pictures/IMG_0726.jpg" # self.image2 = "file:///home/timali/Pictures/out.png" self.currvideo = False @@ -272,18 +270,15 @@ class WebViewer(DisplayWidget): self.frame.evaluateJavaScript("document.getElementById('video').play()") self.currimage = not self.currimage - def setupSelf(self): - self.setWindowTitle(u'OpenLP Display') - self.setWindowFlags(QtCore.Qt.FramelessWindowHint | - QtCore.Qt.WindowStaysOnTopHint) - self.setGeometry(1440, 0, self.screen.current[u'size'].width(), self.screen.current[u'size'].height()) - def setup(self): + log.debug(u'Setup %s for %s ' % ( + self.screens, self.screens.monitor_number)) + self.screen = self.screens.current + self.setVisible(False) + self.setGeometry(self.screen[u'size']) self.webView = QtWebKit.QWebView(self) - self.webView.setGeometry(0, 0, self.screen.current[u'size'].width(), self.screen.current[u'size'].height()) + self.webView.setGeometry(0, 0, self.screen[u'size'].width(), self.screen[u'size'].height()) self.page = self.webView.page() -# html = build_html(None, self.screen, None, self.byteArray) -# self.webView.setHtml(html) self.frame = self.page.mainFrame() self.frame.setScrollBarPolicy(QtCore.Qt.Vertical, QtCore.Qt.ScrollBarAlwaysOff) @@ -302,7 +297,7 @@ class WebViewer(DisplayWidget): def newDisplay(self, image, text, video=None): if not video: - html = build_html(None, self.screen.current, None, image) + html = build_html(None, self.screen, None, image) self.webView.setHtml(html) #class DisplayWidget(QtGui.QGraphicsView): From f3b4a1dae5ebdad214ffc6ef370db91f343257e6 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 11 Jul 2010 13:35:41 +0100 Subject: [PATCH 006/108] Renderer replacement- display splash now. --- openlp/core/lib/htmlbuilder.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openlp/core/lib/htmlbuilder.py b/openlp/core/lib/htmlbuilder.py index 5361fe044..0521b0272 100644 --- a/openlp/core/lib/htmlbuilder.py +++ b/openlp/core/lib/htmlbuilder.py @@ -38,6 +38,7 @@ HTMLSRC = u""" %s %s %s +%s - - -