Fix bug on song saving

Add new screen for Plugin status
Add new presentation plugin code
This commit is contained in:
Tim Bentley 2009-08-13 21:02:38 +01:00
parent a684ecaa1e
commit 10ba1db5f3
7 changed files with 548 additions and 4 deletions

View File

@ -86,18 +86,22 @@ class PluginManager(object):
__import__(modulename, globals(), locals(), [])
except ImportError, e:
log.error(u'Failed to import module %s on path %s for reason %s', modulename, path, e.args[0])
self.plugin_classes = Plugin.__subclasses__()
plugin_classes = Plugin.__subclasses__()
self.plugins = []
self.plugin_list=[]
plugin_objects = []
for p in self.plugin_classes:
for p in plugin_classes:
try:
plugin = p(self.plugin_helpers)
log.debug(u'loaded plugin %s with helpers', unicode(p))
log.debug(u'Plugin: %s', unicode(p))
pList = {u'name': plugin.name, u'version':plugin.version, u'status': u'Inactive'}
if plugin.check_pre_conditions():
log.debug(u'Appending %s ', unicode(p))
plugin_objects.append(plugin)
eventmanager.register(plugin)
pList[u'status'] = u'Active'
self.plugin_list.append(pList)
except TypeError:
log.error(u'loaded plugin %s has no helpers', unicode(p))
self.plugins = sorted(plugin_objects, self.order_by_weight)

View File

@ -27,6 +27,7 @@ from generaltab import GeneralTab
from themestab import ThemesTab
from about import AboutForm
from alertform import AlertForm
from plugindialoglistform import PluginForm
from settingsform import SettingsForm
from servicemanager import ServiceManager
from thememanager import ThemeManager

View File

@ -23,7 +23,8 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.ui import AboutForm, SettingsForm, AlertForm, \
ServiceManager, ThemeManager, MainDisplay, SlideController
ServiceManager, ThemeManager, MainDisplay, SlideController, \
PluginForm
from openlp.core.lib import translate, Plugin, MediaManagerItem, \
SettingsTab, EventManager, RenderManager, PluginConfig, \
SettingsManager, PluginManager, EventType
@ -203,6 +204,14 @@ class Ui_MainWindow(object):
QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.ToolsAlertItem.setIcon(AlertIcon)
self.ToolsAlertItem.setObjectName(u'ToolsAlertItem')
self.PluginItem = QtGui.QAction(MainWindow)
PluginIcon = QtGui.QIcon()
PluginIcon.addPixmap(QtGui.QPixmap(u':/tools/tools_alert.png'),
QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.PluginItem.setIcon(AlertIcon)
self.PluginItem.setObjectName(u'PluginItem')
self.HelpDocumentationItem = QtGui.QAction(MainWindow)
ContentsIcon = QtGui.QIcon()
ContentsIcon.addPixmap(QtGui.QPixmap(u':/system/system_help_contents.png'),
@ -264,6 +273,7 @@ class Ui_MainWindow(object):
self.OptionsMenu.addSeparator()
self.OptionsMenu.addAction(self.OptionsSettingsItem)
self.ToolsMenu.addAction(self.ToolsAlertItem)
self.ToolsMenu.addAction(self.PluginItem)
self.ToolsMenu.addSeparator()
self.ToolsMenu.addAction(self.ToolsAddToolItem)
self.HelpMenu.addAction(self.HelpDocumentationItem)
@ -362,6 +372,12 @@ class Ui_MainWindow(object):
self.ToolsAlertItem.setStatusTip(
translate(u'mainWindow', u'Show an alert message'))
self.ToolsAlertItem.setShortcut(translate(u'mainWindow', u'F7'))
self.PluginItem.setText(translate(u'mainWindow', u'&Plugin'))
self.PluginItem.setStatusTip(
translate(u'mainWindow', u'List the Plugins'))
self.PluginItem.setShortcut(translate(u'mainWindow', u'F8'))
self.HelpDocumentationItem.setText(
translate(u'mainWindow', u'&User Guide'))
self.HelpAboutItem.setText(translate(u'mainWindow', u'&About'))
@ -408,6 +424,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.mainDisplay = MainDisplay(self, screens)
self.generalConfig = PluginConfig(u'General')
self.alertForm = AlertForm(self)
self.pluginForm = PluginForm(self)
self.aboutForm = AboutForm()
self.settingsForm = SettingsForm(self.screenList, self)
# Set up the path with plugins
@ -441,6 +458,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.SIGNAL(u'triggered()'), self.onHelpAboutItemClicked)
QtCore.QObject.connect(self.ToolsAlertItem,
QtCore.SIGNAL(u'triggered()'), self.onToolsAlertItemClicked)
QtCore.QObject.connect(self.PluginItem,
QtCore.SIGNAL(u'triggered()'), self.onPluginItemClicked)
QtCore.QObject.connect(self.OptionsSettingsItem,
QtCore.SIGNAL(u'triggered()'), self.onOptionsSettingsItemClicked)
#warning cyclic dependency
@ -514,6 +533,13 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
"""
self.alertForm.exec_()
def onPluginItemClicked(self):
"""
Show the Plugin form
"""
self.pluginForm.load()
self.pluginForm.exec_()
def onOptionsSettingsItemClicked(self):
"""
Show the Settings dialog

View File

@ -0,0 +1,76 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'plugindialoglistform.ui'
#
# Created: Thu Aug 13 05:52:06 2009
# by: PyQt4 UI code generator 4.5.4
#
# WARNING! All changes made in this file will be lost!
import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate
class PluginForm(QtGui.QDialog):
global log
log = logging.getLogger(u'PluginForm')
def __init__(self, parent=None):
QtGui.QDialog.__init__(self, None)
self.parent = parent
self.setupUi(self)
log.debug(u'Defined')
def setupUi(self, PluginViewDialog):
PluginViewDialog.setObjectName("PluginViewDialog")
PluginViewDialog.resize(400, 393)
self.PluginViewList = QtGui.QTableWidget(PluginViewDialog)
self.PluginViewList.setGeometry(QtCore.QRect(20, 10, 371, 331))
self.PluginViewList.setObjectName("PluginViewList")
self.PluginViewList.setShowGrid(False)
self.PluginViewList.setGridStyle(QtCore.Qt.SolidLine)
self.PluginViewList.setSortingEnabled(False)
self.PluginViewList.setColumnCount(3)
item = QtGui.QTableWidgetItem()
self.PluginViewList.setHorizontalHeaderItem(0, item)
item = QtGui.QTableWidgetItem()
self.PluginViewList.setHorizontalHeaderItem(1, item)
item = QtGui.QTableWidgetItem()
self.PluginViewList.setHorizontalHeaderItem(2, item)
self.PluginViewList.horizontalHeader().setVisible(True)
self.PluginViewList.verticalHeader().setVisible(False)
self.ButtonBox = QtGui.QDialogButtonBox(PluginViewDialog)
self.ButtonBox.setGeometry(QtCore.QRect(220, 350, 170, 25))
self.ButtonBox.setStandardButtons(QtGui.QDialogButtonBox.Ok)
self.ButtonBox.setObjectName("ButtonBox")
self.retranslateUi(PluginViewDialog)
QtCore.QObject.connect(self.ButtonBox, QtCore.SIGNAL("accepted()"), PluginViewDialog.close)
QtCore.QMetaObject.connectSlotsByName(PluginViewDialog)
def retranslateUi(self, PluginViewDialog):
PluginViewDialog.setWindowTitle(QtGui.QApplication.translate("PluginViewDialog", "Plugin list", None, QtGui.QApplication.UnicodeUTF8))
self.PluginViewList.horizontalHeaderItem(0).setText(QtGui.QApplication.translate("PluginViewDialog", "Name", None, QtGui.QApplication.UnicodeUTF8))
self.PluginViewList.horizontalHeaderItem(1).setText(QtGui.QApplication.translate("PluginViewDialog", "Version", None, QtGui.QApplication.UnicodeUTF8))
self.PluginViewList.horizontalHeaderItem(2).setText(QtGui.QApplication.translate("PluginViewDialog", "Status", None, QtGui.QApplication.UnicodeUTF8))
def load(self):
"""
Load the plugin details into the screen
"""
for plugin in self.parent.plugin_manager.plugin_list:
row = self.PluginViewList.rowCount()
self.PluginViewList.setRowCount(row + 1)
item1 = QtGui.QTableWidgetItem(plugin[u'name'])
item1.setTextAlignment(QtCore.Qt.AlignVCenter)
item2 = QtGui.QTableWidgetItem(plugin[u'version'])
item2.setTextAlignment(QtCore.Qt.AlignVCenter)
item3 = QtGui.QTableWidgetItem(plugin[u'status'])
item3.setTextAlignment(QtCore.Qt.AlignVCenter)
self.PluginViewList.setItem(row, 0, item1)
self.PluginViewList.setItem(row, 1, item2)
self.PluginViewList.setItem(row, 2, item3)
self.PluginViewList.setRowHeight(row, 15)

View File

@ -0,0 +1,329 @@
# -*- 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 , subprocess
import time
import uno
from PyQt4 import QtCore, QtGui
from openlp.core.lib import OpenLPToolbar, translate
from openlp.core.ui.slidecontroller import MasterToolbar
class impressToolbar(MasterToolbar):
def __init__(self):
self.startOpenoffice()
self.isLive = True
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
def defineToolbar(self):
# Controller toolbar
self.Toolbar = OpenLPToolbar(self)
sizeToolbarPolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Fixed)
sizeToolbarPolicy.setHorizontalStretch(0)
sizeToolbarPolicy.setVerticalStretch(0)
sizeToolbarPolicy.setHeightForWidth(
self.Toolbar.sizePolicy().hasHeightForWidth())
self.Toolbar.setSizePolicy(sizeToolbarPolicy)
if self.isLive:
self.Toolbar.addToolbarButton(u'First Slide',
u':/slides/slide_first.png',
translate(u'SlideController', u'Move to first'),
self.onSlideSelectedFirst)
self.Toolbar.addToolbarButton(u'Previous Slide',
u':/slides/slide_previous.png',
translate(u'SlideController', u'Move to previous'),
self.onSlideSelectedPrevious)
self.Toolbar.addToolbarButton(u'Next Slide',
u':/slides/slide_next.png',
translate(u'SlideController', u'Move to next'),
self.onSlideSelectedNext)
if self.isLive:
self.Toolbar.addToolbarButton(u'Last Slide',
u':/slides/slide_last.png',
translate(u'SlideController', u'Move to last'),
self.onSlideSelectedLast)
self.Toolbar.addSeparator()
self.Toolbar.addToolbarButton(u'Close Screen',
u':/slides/slide_close.png',
translate(u'SlideController', u'Close Screen'),
self.onBlankScreen)
def serviceLoaded(self):
"""
method to allow toolbars to know when the service item
is fully in place
"""
pass
def onSlideSelectedFirst(self):
"""
Go to the first slide.
"""
self.PreviewListWidget.selectRow(0)
self.onSlideSelected()
def onSlideSelectedNext(self):
"""
Go to the next slide.
"""
row = self.PreviewListWidget.currentRow() + 1
if row == self.PreviewListWidget.rowCount():
row = 0
self.PreviewListWidget.selectRow(row)
self.onSlideSelected()
def onSlideSelectedPrevious(self):
"""
Go to the previous slide.
"""
row = self.PreviewListWidget.currentRow() - 1
if row == -1:
row = self.PreviewListWidget.rowCount() - 1
self.PreviewListWidget.selectRow(row)
self.onSlideSelected()
def onSlideSelectedLast(self):
"""
Go to the last slide.
"""
self.PreviewListWidget.selectRow(self.PreviewListWidget.rowCount() - 1)
self.onSlideSelected()
def onBlankScreen(self):
"""
Blank the screen.
"""
self.mainDisplay.blankDisplay()
def onSlideSelected(self):
"""
Generate the preview when you click on a slide.
if this is the Live Controller also display on the screen
"""
row = self.PreviewListWidget.currentRow()
if row > -1 and row < self.PreviewListWidget.rowCount():
label = self.PreviewListWidget.cellWidget(row, 0)
smallframe = label.pixmap()
frame = self.serviceitem.frames[row][u'image']
self.SlidePreview.setPixmap(smallframe)
if self.isLive:
self.mainDisplay.frameView(frame)
def addServiceItem(self, serviceitem, slideno = 1):
"""
Loads a ServiceItem into the system from plugins
Display the first slide
"""
log.debug(u'add Service Item')
# serviceitem.render()
# self.addServiceManagerItem(serviceitem, 0)
def addServiceManagerItem(self, serviceitem, slideno):
"""
Loads a ServiceItem into the system from ServiceManager
Display the slide number passed
"""
log.debug(u'add Service Manager Item')
# self.PreviewListWidget.clear()
# self.PreviewListWidget.setRowCount(0)
# self.serviceitem = serviceitem
# framenumber = 0
# for frame in self.serviceitem.frames:
# self.PreviewListWidget.setRowCount(self.PreviewListWidget.rowCount() + 1)
# pixmap = QtGui.QPixmap.fromImage(frame[u'image'])
# item = QtGui.QTableWidgetItem()
# label = QtGui.QLabel()
# label.setMargin(15)
# label.setScaledContents(True)
# width = 300
# height = width * pixmap.height() / pixmap.width()
# label.setPixmap(pixmap)
# self.PreviewListWidget.setCellWidget(framenumber, 0,label)
# self.PreviewListWidget.setItem( framenumber, 0, item)
# self.PreviewListWidget.setRowHeight(framenumber, height)
# self.PreviewListWidget.setColumnWidth(0, width)
# framenumber += 1
# if slideno > self.PreviewListWidget.rowCount():
# self.PreviewListWidget.selectRow(self.PreviewListWidget.rowCount())
# else:
# self.PreviewListWidget.selectRow(slideno)
# self.onSlideSelected()
# self.serviceLoaded()
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

@ -356,7 +356,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.processTitle()
self.songmanager.save_song(self.song)
if self.title_change:
self.eventmanager.post_event(Event(EventType.LoadSongList), u'EditSongForm')
self.eventmanager.post_event(Event(EventType.LoadSongList, u'EditSongForm'))
self.close()
def processLyrics(self):

View File

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PluginViewDialog</class>
<widget class="QWidget" name="PluginViewDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>393</height>
</rect>
</property>
<property name="windowTitle">
<string>Plugin list</string>
</property>
<widget class="QTableWidget" name="PluginViewList">
<property name="geometry">
<rect>
<x>20</x>
<y>10</y>
<width>371</width>
<height>331</height>
</rect>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
<property name="gridStyle">
<enum>Qt::SolidLine</enum>
</property>
<property name="rowCount">
<number>1</number>
</property>
<attribute name="horizontalHeaderVisible">
<bool>true</bool>
</attribute>
<attribute name="horizontalHeaderShowSortIndicator" stdset="0">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<row/>
<column>
<property name="text">
<string>Name</string>
</property>
</column>
<column>
<property name="text">
<string>Version</string>
</property>
</column>
<column>
<property name="text">
<string>Status</string>
</property>
</column>
<item row="0" column="0">
<property name="text">
<string>qqq</string>
</property>
</item>
<item row="0" column="1">
<property name="text">
<string>aaa</string>
</property>
</item>
<item row="0" column="2">
<property name="text">
<string>ccc</string>
</property>
</item>
</widget>
<widget class="QDialogButtonBox" name="ButtonBox">
<property name="geometry">
<rect>
<x>220</x>
<y>350</y>
<width>170</width>
<height>25</height>
</rect>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Ok</set>
</property>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>ButtonBox</sender>
<signal>accepted()</signal>
<receiver>PluginViewDialog</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>370</x>
<y>364</y>
</hint>
<hint type="destinationlabel">
<x>460</x>
<y>367</y>
</hint>
</hints>
</connection>
</connections>
</ui>