Various changes

bzr-revno: 526
This commit is contained in:
Tim Bentley 2009-09-07 20:18:56 +01:00
commit 3c4e9a957f
13 changed files with 190 additions and 221 deletions

View File

@ -94,6 +94,7 @@ class EventReceiver(QtCore.QObject):
``msg``
Defaults to *None*. The message to send with the event.
"""
log.debug(u'Event %s passed with payload %s' % (event, msg))
self.emit(QtCore.SIGNAL(event), msg)

View File

@ -34,8 +34,14 @@ class SettingsManager(object):
self.width = self.screen[u'size'].width()
self.height = self.screen[u'size'].height()
self.mainwindow_height = self.height * 0.8
self.mainwindow_docbars = self.width / 3
self.mainwindow_docbars = self.width / 5
if self.mainwindow_docbars > 300:
self.mainwindow_docbars > 300
self.mainwindow_slidecontroller = self.width / 6
self.slidecontroller = ((self.width - (self.mainwindow_docbars * 3 ) / 2 ) / 2 ) -100
self.slidecontroller_image = self.slidecontroller - 50
print self.width, self.mainwindow_docbars, self.slidecontroller, self.slidecontroller_image
self.showMediaManager = str_to_bool( ConfigHelper.get_config(
u'user interface', u'display mediamanager', True))
self.showServiceManager = str_to_bool(ConfigHelper.get_config(

View File

@ -68,7 +68,7 @@ class SlideController(QtGui.QWidget):
self.settingsmanager = settingsmanager
self.isLive = isLive
self.parent = parent
self.image_list = [u'Start Loop', u'Stop Loop', u'Loop Spearator', u'Image SpinBox']
self.image_list = [u'Start Loop', u'Stop Loop', u'Loop Separator', u'Image SpinBox']
self.timer_id = 0
self.item = None
self.Panel = QtGui.QWidget(parent.ControlSplitter)
@ -131,7 +131,7 @@ class SlideController(QtGui.QWidget):
translate(u'SlideController', u'Close Screen'),
self.onBlankScreen)
if isLive:
self.Toolbar.addToolbarSeparator(u'Loop Spearator')
self.Toolbar.addToolbarSeparator(u'Loop Separator')
self.Toolbar.addToolbarButton(u'Start Loop',
u':/media/media_time.png',
translate(u'SlideController', u'Start continuous loop'),

View File

@ -18,10 +18,11 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
"""
from impresscontroller import ImpressController
from powerpointcontroller import PowerpointController
from messagelistener import MessageListener
from mediaitem import PresentationMediaItem
from presentationtab import PresentationTab
__all__ = ['PresentationMediaItem', 'PresentationTab',
'ImpressController', 'MessageListener']
'ImpressController', 'ImpressController', 'PowerpointController', 'MessageListener']

View File

@ -1,188 +0,0 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
"""
OpenLP - Open Source Lyrics Projection
Copyright (c) 2008 Raoul Snyman
Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
"""
# OOo API documentation:
# http://api.openoffice.org/docs/common/ref/com/sun/star/presentation/XSlideShowController.html
# http://docs.go-oo.org/sd/html/classsd_1_1SlideShow.html
# http://www.oooforum.org/forum/viewtopic.phtml?t=5252
# http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Working_with_Presentations
# http://mail.python.org/pipermail/python-win32/2008-January/006676.html
import os
import subprocess
import time
import uno
class Openoffice(object):
def __init__(self):
self.startOpenoffice()
def createResolver(self):
self.localContext = uno.getComponentContext()
self.resolver = self.localContext.ServiceManager.createInstanceWithContext(u'com.sun.star.bridge.UnoUrlResolver', self.localContext)
try:
self.ctx = self.resolver.resolve(u'uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext')
except:
return False
return True
def buildEnvironment(self):
self.smgr = self.ctx.ServiceManager
self.desktop = self.smgr.createInstanceWithContext( "com.sun.star.frame.Desktop", self.ctx )
self.model = self.desktop.getCurrentComponent()
text = self.model.Text
cursor = text.createTextCursor()
text.insertString(cursor, "Hello world", 0)
self.ctx.ServiceManager
self.createApp()
if self._sm == None:
# start OO here
# Create output log file
time.sleep(10)
self.createApp()
def startOpenoffice(self):
cmd = u'openoffice.org -nologo -norestore -invisible -minimized -impress' + u'"' + u'-accept=socket,host=localhost,port=2002;urp;'+ u'"'
retval = subprocess.Popen(cmd, shell=True)
self.oopid = retval.pid
def checkOoPid(self):
if os.name == u'nt':
import win32api
handle = win32api.OpenProcess(PROCESS_TERMINATE, False, self.oopid)
#todo need some code here
return True
elif os.name == u'mac':
pass
else:
procfile = open("/proc/%d/stat" %(self.oopid))
file = procfile.readline().split()[1]
print file
if file == u'(soffice)' or file == u'(openoffice.org)':
return True
return False
def createApp(self):
try:
self._app = self._sm.createInstance( "com.sun.star.frame.Desktop" )
print "started"
except:
print "oops"
self._sm = None
self._app = None
return
def getApp(self):
if self._app == None:
self.createApp()
if self._app == None:
return None
return self._app
app = property(getApp)
def quit(self):
self._app.Terminate()
self._app = None
self._sm = None
class ImpressCOMPres(object):
def __init__(self, oooApp, filename):
self.oooApp = oooApp
self.filename = filename
self.open()
def getPres(self):
if self._pres == None:
self.open()
return self._pres
pres = property(getPres)
def open(self):
self.comp = self.oooApp.app.loadComponentFromURL(u'file:///' + self.filename, '_blank', 0, [])
self.presdoc = self.comp.getPresentation()
self.presdoc.start()
self._pres = self.presdoc.getController()
def close(self):
self.pres.deactivate()
self.presdoc.end()
self.comp.dispose()
self._pres = None
self.presdoc = None
self.comp = None
def isActive(self):
return self.pres.isRunning() and self.pres.isActive()
def resume(self):
return self.pres.resume()
def pause(self):
return self.pres.pause()
def blankScreen(self):
self.pres.blankScreen(0)
def stop(self):
self.pres.deactivate()
# self.presdoc.end()
def go(self):
self.pres.activate()
# self.presdoc.start()
def getSlideNumber(self):
return self.pres.getCurrentSlideIndex
def setSlideNumber(self, slideno):
self.pres.gotoSlideIndex(slideno)
slideNumber = property(getSlideNumber, setSlideNumber)
def nextStep(self):
self.pres.gotoNextEffect()
def prevStep(self):
self.pres.gotoPreviousSlide()
def moveWindow(self, top, height, left, width):
# position the window somehow
pass
class ImpressCOMSlide(object):
def __init__(self, pres, index):
self.pres = pres
self.slide = pres.getSlideByIndex(index)
def preview(self):
if self.preview == None:
# get a slide somehow
pass
return self.preview
if __name__ == '__main__':
ooo = Openoffice()
ooo.createResolver()
show = ImpressCOMPres(ooo, u'/home/timali/test1.odp')
show.go()
#show.resume()
#show.nextStep()

View File

@ -35,6 +35,11 @@ import sys
from PyQt4 import QtCore
class ImpressController(object):
"""
Class to control interactions with Impress Presentations
It creates the runtime Environment , Loads the and Closes the Presentation
As well as trigggering the correct activities based on the users input
"""
global log
log = logging.getLogger(u'ImpressController')
@ -46,6 +51,11 @@ class ImpressController(object):
self.startOpenoffice()
def startOpenoffice(self):
"""
Loads a running version of OpenOffice inthe background.
It is not displayed to the user but is available to the Uno interface
when required.
"""
log.debug(u'start Openoffice')
cmd = u'openoffice.org -nologo -norestore -minimized -headless ' + u'"' + u'-accept=socket,host=localhost,port=2002;urp;'+ u'"'
self.process = QtCore.QProcess()
@ -53,15 +63,34 @@ class ImpressController(object):
self.process.waitForStarted()
def kill(self):
"""
Called at system exit to clean up any running presentations
"""
log.debug(u'Kill')
self.closePresentation()
def loadPresentation(self, presentation):
log.debug(u'create Resolver')
try:
"""
Called when a presentation is added to the SlideController.
It builds the environment, starts communcations with the background
OpenOffice task started earlier. If OpenOffice is not present is ts started.
Once the environment is available the presentation is loaded and started.
``presentation``
The file name of the presentatios to the run.
"""
log.debug(u'LoadPresentation')
ctx = None
loop = 0
context = uno.getComponentContext()
resolver = context.ServiceManager.createInstanceWithContext(u'com.sun.star.bridge.UnoUrlResolver', context)
while ctx == None and loop < 3:
try:
ctx = resolver.resolve(u'uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext')
except:
self.startOpenoffice()
loop += 1
try:
smgr = ctx.ServiceManager
desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop", ctx )
url = uno.systemPathToFileUrl(presentation)
@ -70,7 +99,7 @@ class ImpressController(object):
self.document = desktop.loadComponentFromURL(url, "_blank", 0, properties)
self.presentation = self.document.getPresentation()
self.presentation.start()
self.xSlideSshowController = desktop.getCurrentComponent().Presentation.getController()
self.xSlideShowController = desktop.getCurrentComponent().Presentation.getController()
except:
log.error(u'Failed reason %s' % sys.exc_info())
@ -116,8 +145,14 @@ class ImpressController(object):
slideNumber = property(getSlideNumber, setSlideNumber)
def nextStep(self):
self.xSlideSshowController.gotoNextEffect()
"""
Triggers the next effect of slide on the running presentation
"""
self.xSlideShowController.gotoNextEffect()
def previousStep(self):
self.xSlideSshowController.gotoPreviousSlide()
"""
Triggers the previous slide on the running presentation
"""
self.xSlideShowController.gotoPreviousSlide()

View File

@ -59,15 +59,30 @@ class MessageListener(object):
self.controllers[self.handler].loadPresentation(file)
def next(self, message):
"""
Based on the handler passed at startup triggers the next slide event
"""
self.controllers[self.handler].nextStep()
def previous(self, message):
"""
Based on the handler passed at startup triggers the previous slide event
"""
self.controllers[self.handler].previousStep()
def shutDown(self, message):
"""
Based on the handler passed at startup triggers slide show to shut down
"""
self.controllers[self.handler].closePresentation()
def decodeMessage(self, message):
"""
Splits the message from the SlideController into it's component parts
``message``
Message containing Presentaion handler name and file to be presented.
"""
bits = message.split(u':')
file = os.path.join(bits[1], bits[2])
return bits[0], file

View File

@ -1,14 +1,49 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
"""
OpenLP - Open Source Lyrics Projection
Copyright (c) 2008 Raoul Snyman
Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley,
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
"""
try:
from win32com.client import Dispatch
except:
pass
import logging
# PPT API documentation:
# http://msdn.microsoft.com/en-us/library/aa269321(office.10).aspx
class PowerPointApp(object):
def __init__(self):
self.createApp()
class PowerpointController(object):
"""
Class to control interactions with Powerpoint Presentations
It creates the runtime Environment , Loads the and Closes the Presentation
As well as trigggering the correct activities based on the users input
"""
global log
log = logging.getLogger(u'PowerpointController')
def createApp(self):
def __init__(self):
log.debug(u'Initialising')
self.process = None
self.document = None
self.presentation = None
self.startPowerpoint()
def startPowerpoint(self):
try:
self._app = Dispatch(u'PowerPoint.Application')
except:
@ -33,6 +68,7 @@ class PowerPointApp(object):
self._app = None
class PowerPointPres(object):
def __init__(self, pptApp, filename):
self.pptApp = pptApp
self.filename = filename
@ -101,7 +137,7 @@ class PowerPointPres(object):
self.resume()
self.pres.SlideShowWindow.View.GotoSlide(slideno)
currentSlideIndex = property(getSlideNumber, setSlideNumber)
#currentSlideIndex = property(getSlideNumber, setSlideNumber)
def nextStep(self):
if not self.isActive():
@ -136,4 +172,3 @@ class PowerPointSlide(object):
# w.CloseClipboard()
return self.preview

View File

@ -1,3 +1,23 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
"""
OpenLP - Open Source Lyrics Projection
Copyright (c) 2008 Raoul Snyman
Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley,
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
"""
import sys
import win32api
from PyQt4 import QtGui, QtCore

View File

@ -56,6 +56,10 @@ class PresentationTab(SettingsTab):
self.PowerpointCheckBox.setTristate(False)
self.PowerpointCheckBox.setObjectName(u'PowerpointCheckBox')
self.VerseDisplayLayout.addWidget(self.PowerpointCheckBox, 0, 0, 1, 1)
self.PowerpointViewerCheckBox = QtGui.QCheckBox(self.VerseDisplayGroupBox)
self.PowerpointViewerCheckBox.setTristate(False)
self.PowerpointViewerCheckBox.setObjectName(u'PowerpointViewerCheckBox')
self.VerseDisplayLayout.addWidget(self.PowerpointViewerCheckBox, 1, 0, 1, 1)
self.ImpressCheckBox = QtGui.QCheckBox(self.VerseDisplayGroupBox)
self.ImpressCheckBox.setTristate(False)
self.ImpressCheckBox.setObjectName(u'ImpressCheckBox')
@ -84,12 +88,15 @@ class PresentationTab(SettingsTab):
def retranslateUi(self):
self.PowerpointCheckBox.setText(translate(u'PresentationTab', 'Powerpoint available:'))
self.PowerpointViewerCheckBox.setText(translate(u'PresentationTab', 'PowerpointViewer available:'))
self.ImpressCheckBox.setText(translate(u'PresentationTab', 'Impress available:'))
def load(self):
self.PowerpointCheckBox.setChecked(int(self.config.get_config(u'Powerpoint', 0)))
self.PowerpointViewerCheckBox.setChecked(int(self.config.get_config(u'Powerpoint Viewer', 0)))
self.ImpressCheckBox.setChecked(int(self.config.get_config(u'Impress', 0)))
def save(self):
self.config.set_config(u'Powerpoint', unicode(self.PowerpointCheckBox.checkState()))
self.config.set_config(u'Powerpoint Viewer', unicode(self.PowerpointViewerCheckBox.checkState()))
self.config.set_config(u'Impress', unicode(self.ImpressCheckBox.checkState()))

View File

@ -25,7 +25,8 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, MediaManagerItem
from openlp.plugins.presentations.lib import PresentationMediaItem, PresentationTab, ImpressController
from openlp.plugins.presentations.lib import PresentationMediaItem, PresentationTab, \
ImpressController, PowerpointController
class PresentationPlugin(Plugin):
@ -74,7 +75,25 @@ class PresentationPlugin(Plugin):
openoffice = ImpressController()
self.registerControllers(u'Impress', openoffice)
except:
log.error(u'Reason : %s', sys.exc_info())#[0])
log.error(u'Reason : %s', sys.exc_info())
#Lets see if Impress is required (Default is Not wanted)
if int(self.config.get_config(u'Powerpoint', 0)) == 2:
try:
#Check to see if we are Win32
from win32com.client import Dispatch
powerpoint = PowerpointController()
self.registerControllers(u'Powerpoint', powerpoint)
except:
log.error(u'Reason : %s', sys.exc_info())
#Lets see if Impress is required (Default is Not wanted)
if int(self.config.get_config(u'Powerpoint Viewer', 0)) == 2:
try:
#Check to see if we are Win32
from win32com.client import Dispatch
powerpoint = PowerpointController()
self.registerControllers(u'Powerpoint Viewer', powerpoint)
except:
log.error(u'Reason : %s', sys.exc_info())
#If we have no available controllers disable plugin
if len(self.controllers) > 0:
return True

View File

@ -43,6 +43,9 @@ class RemoteTab(SettingsTab):
self.RemotePortSpinBox.setObjectName(u'RemotePortSpinBox')
self.RemotePortSpinBox.setMaximum(32767)
self.RemoteModeLayout.addWidget(self.RemotePortSpinBox)
self.RemoteActive = QtGui.QCheckBox(self.RemoteModeGroupBox)
self.RemoteActive.setObjectName(u'RemotePortSpinBox')
self.RemoteModeLayout.addWidget(self.RemoteActive)
self.WarningLabel = QtGui.QLabel(self.RemoteModeGroupBox)
self.WarningLabel.setObjectName(u'WarningLabel')
self.RemoteModeLayout.addWidget(self.WarningLabel)
@ -50,10 +53,14 @@ class RemoteTab(SettingsTab):
def retranslateUi(self):
self.RemoteModeGroupBox.setTitle(translate(u'RemoteTab', u'Remotes Receiver Port'))
self.RemoteActive.setText(translate(u'RemoteTab', 'Remote available:'))
self.WarningLabel.setText(translate(u'RemoteTab', u'A restart is needed for this change to become effective'))
def load(self):
self.RemotePortSpinBox.setValue(int(self.config.get_config(u'remote port', 4316)))
self.RemoteActive.setChecked(int(self.config.get_config(u'startup', 0)))
def save(self):
self.config.set_config(u'remote port', unicode(self.RemotePortSpinBox.value()))
self.config.set_config(u'startup', unicode(self.RemoteActive.checkState()))

View File

@ -40,6 +40,17 @@ class RemotesPlugin(Plugin):
QtCore.QObject.connect(self.server,
QtCore.SIGNAL(u'readyRead()'), self.readData)
def check_pre_conditions(self):
"""
Check to see if remotes is required
"""
log.debug('check_pre_conditions')
#Lets see if Remote is required
if int(self.config.get_config(u'startup', 0)) == 2:
return True
else:
return False
def get_settings_tab(self):
"""
Create the settings Tab