← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~trb143/openlp/trb143 into lp:openlp

 

Tim Bentley has proposed merging lp:~trb143/openlp/trb143 into lp:openlp.

Requested reviews:
    openlp.org Core (openlp-core): rereview
-- 
https://code.launchpad.net/~trb143/openlp/trb143/+merge/4948
Your team openlp.org Core is subscribed to branch lp:openlp.
=== modified file 'openlp/core/lib/__init__.py'
--- openlp/core/lib/__init__.py	2009-03-19 17:36:06 +0000
+++ openlp/core/lib/__init__.py	2009-03-23 20:18:06 +0000
@@ -22,6 +22,8 @@
 from settingstab import SettingsTab
 from mediamanageritem import MediaManagerItem
 from event import Event
+from event import EventType
+from eventmanager import EventManager
 from xmlrootclass import XmlRootClass
 from serviceitem import ServiceItem
 from eventreceiver import Receiver
@@ -30,6 +32,6 @@
 from songxmlhandler import SongXMLBuilder
 from songxmlhandler import SongXMLParser
 
-__all__ = ['PluginConfig', 'Plugin', 'SettingsTab', 'MediaManagerItem', 'Event',
+__all__ = ['PluginConfig', 'Plugin', 'SettingsTab', 'MediaManagerItem', 'Event', 'EventType'
            'XmlRootClass', 'ServiceItem', 'Receiver', 'OpenLPToolbar', 'SongXMLBuilder', 
-           'SongXMLParser']
+           'SongXMLParser', 'EventManager']

=== modified file 'openlp/core/lib/event.py'
--- openlp/core/lib/event.py	2008-12-01 09:33:16 +0000
+++ openlp/core/lib/event.py	2009-03-23 20:18:06 +0000
@@ -3,7 +3,7 @@
 """
 OpenLP - Open Source Lyrics Projection
 Copyright (c) 2008 Raoul Snyman
-Portions copyright (c) 2008 Martin Thompson, Tim Bentley, Scott Guerreri,
+Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley, Scott Guerreri,
     Carsten Tingaard, Jonathan Corwin
 
 This program is free software; you can redistribute it and/or modify it under
@@ -46,6 +46,9 @@
     """
     Provides an Event class to encapsulate events within openlp.org.
     """
-
-    def __init__(self, event_type=EventType.Default):
-        self.type = event_type
+    def __init__(self, event_type=EventType.Default, payload=None):
+        self.event_type = event_type
+        self.payload = payload
+        
+    def get_type(self):
+        return self.event_type

=== added file 'openlp/core/lib/eventmanager.py'
--- openlp/core/lib/eventmanager.py	1970-01-01 00:00:00 +0000
+++ openlp/core/lib/eventmanager.py	2009-03-25 20:30:48 +0000
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=80
+"""
+OpenLP - Open Source Lyrics Projection
+Copyright (c) 2008 Raoul Snyman
+Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley, Scott Guerreri,
+    Carsten Tingaard, Jonathan Corwin
+
+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 os
+import logging
+
+class EventManager(object):
+    """
+    A mechanism to send events to all registered endpoints
+    the endpoints are registered and listen with a handle_event method
+    the endpoint will decide whether to do somthing with the event or ignore it
+    
+    """
+    global log
+    log=logging.getLogger(u'EventManager')
+    
+    def __init__(self):
+        self.endpoints=[]
+        log.info(u'Initialising')
+        
+    def register(self, plugin):
+        log.debug(u'plugin %s registered with EventManager'%plugin)        
+        self.endpoints.append(plugin)
+        
+    def post_event(self, event):
+        log.debug(u'post event called for event %s'%event.get_type)
+        for point in self.endpoints:
+            point.handle_event(event)
+

=== modified file 'openlp/core/lib/plugin.py'
--- openlp/core/lib/plugin.py	2009-03-01 09:13:27 +0000
+++ openlp/core/lib/plugin.py	2009-03-23 20:18:06 +0000
@@ -67,7 +67,7 @@
         and screen number.
     """
 
-    def __init__(self, name=None, version=None, preview_controller=None, live_controller=None):
+    def __init__(self, name=None, version=None, plugin_helpers=None):
         """
         This is the constructor for the plugin object. This provides an easy
         way for descendent plugins to populate common data. This method *must*
@@ -88,8 +88,10 @@
         self.weight = 0
         # Set up logging
         self.log = logging.getLogger(self.name)
-        self.preview_controller=preview_controller
-        self.live_controller=live_controller
+        self.preview_controller=plugin_helpers[u'preview']
+        self.live_controller=plugin_helpers[u'live']
+        self.theme_manager=plugin_helpers[u'theme']
+        self.event_manager=plugin_helpers[u'event']        
         
     def check_pre_conditions(self):
         """

=== modified file 'openlp/core/pluginmanager.py'
--- openlp/core/pluginmanager.py	2009-03-12 20:19:24 +0000
+++ openlp/core/pluginmanager.py	2009-03-25 20:30:48 +0000
@@ -3,7 +3,7 @@
 """
 OpenLP - Open Source Lyrics Projection
 Copyright (c) 2008 Raoul Snyman
-Portions copyright (c) 2008 Martin Thompson, Tim Bentley,
+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
@@ -22,7 +22,7 @@
 import sys
 import logging
 
-from openlp.core.lib import Plugin
+from openlp.core.lib import Plugin, EventManager
 
 class PluginManager(object):
     """
@@ -30,15 +30,15 @@
     and executes all the hooks, as and when necessary.
     """
     global log
-    log=logging.getLogger("PluginMgr")
-    log.info("Plugin manager loaded")
+    log=logging.getLogger(u'PluginMgr')
+    log.info(u'Plugin manager loaded')
 
     def __init__(self, dir):
         """
         The constructor for the plugin manager.
         Passes the controllers on to the plugins for them to interact with via their ServiceItems
         """
-        log.info("Plugin manager initing")
+        log.info(u'Plugin manager initing')
         if not dir in sys.path:
             log.debug("Inserting %s into sys.path", dir)
             sys.path.insert(0, dir)
@@ -48,12 +48,11 @@
         # this has to happen after the UI is sorted self.find_plugins(dir)
         log.info("Plugin manager done init")
 
-    def find_plugins(self, dir, preview_controller, live_controller): # xxx shouldn't dir come from self.basepath
+    def find_plugins(self, dir, plugin_helpers, eventmanager): # TODO shouldn't dir come from self.basepath
         """
         Scan the directory dir for objects inheriting from openlp.plugin
         """
-        self.preview_controller=preview_controller
-        self.live_controller=live_controller
+        self.plugin_helpers = plugin_helpers
         startdepth=len(os.path.abspath(dir).split(os.sep))
         log.debug("find plugins %s at depth %d" %( str(dir), startdepth))
 
@@ -80,16 +79,15 @@
         plugin_objects = []
         for p in self.plugin_classes:
             try:
-                plugin = p(self.preview_controller, self.live_controller)
-                log.debug('loaded plugin' + str(p) + ' with controllers'+str(self.preview_controller)+str(self.live_controller))
+                plugin = p(self.plugin_helpers)
+                log.debug(u'loaded plugin %s with helpers'%str(p))
+                log.debug("Plugin="+str(p))
+                if plugin.check_pre_conditions():
+                    log.debug("Appending "+str(p))
+                    plugin_objects.append(plugin)
+                    eventmanager.register(plugin)
             except TypeError:
-                # TODO: need to get rid of this once all plugins are up to date
-                plugin = p()
-                log.debug('loaded plugin' + str(p) + ' with no controllers')
-            log.debug("Plugin="+str(p))
-            if plugin.check_pre_conditions():
-                log.debug("Appending "+str(p))
-                plugin_objects.append(plugin)
+                log.error(u'loaded plugin %s has no helpers'%str(p))
         self.plugins = sorted(plugin_objects, self.order_by_weight)
 
     def order_by_weight(self, x, y):
@@ -105,8 +103,6 @@
             if media_manager_item is not None:
                 log.debug('Inserting media manager item from %s' % plugin.name)
                 mediatoolbox.addItem(media_manager_item, plugin.icon, media_manager_item.title)
-                # TODO: These shouldn't be called here...
-                plugin.initialise()
 
     def hook_settings_tabs(self, settingsform=None):
         """
@@ -137,5 +133,19 @@
         for plugin in self.plugins:
             plugin.add_export_menu_item(export_menu)
 
-    def hook_handle_event(self, event):
-        pass
+    def hook_handle_event(self, eventmanager):
+        for plugin in self.plugins:
+            handle_event = plugin.handle_event(None)
+            print plugin, handle_event
+#            if settings_tab is not None:
+#                log.debug('Inserting settings tab item from %s' % plugin.name)
+#                settingsform.addTab(settings_tab)
+#            else:
+#                log.debug('No settings in %s' % plugin.name)
+    def initialise_plugins(self):
+        """
+        Loop through all the plugins and give them an opportunity to add an item
+        to the export menu.
+        """
+        for plugin in self.plugins:
+            plugin.initialise()

=== modified file 'openlp/core/render.py'
--- openlp/core/render.py	2009-03-12 20:19:24 +0000
+++ openlp/core/render.py	2009-03-22 07:13:34 +0000
@@ -44,8 +44,10 @@
         self._theme=None
         self._bg_image_filename=None
         self._paint=None
+        
     def set_debug(self, debug):
         self._debug=debug
+        
     def set_theme(self, theme):
         self._theme=theme
         if theme.BackgroundType == 2:
@@ -56,6 +58,7 @@
         self._bg_image_filename=filename
         if self._paint is not None:
             self.scale_bg_image()
+            
     def scale_bg_image(self):
         assert self._paint
         i=QtGui.QImage(self._bg_image_filename)
@@ -81,6 +84,7 @@
         self._paint=p
         if self._bg_image_filename is not None:
             self.scale_bg_image()
+            
     def set_words_openlp(self, words):
 #         print "set words openlp", words
         verses=[]
@@ -95,6 +99,7 @@
             verses_text.append('\n'.join(v).lstrip()) # remove first \n
 
         return verses_text
+        
     def render_screen(self, screennum):
         print "render screen\n", screennum, self.words[screennum]
         import time
@@ -106,6 +111,7 @@
     def set_text_rectangle(self, rect):
         """ Sets the rectangle within which text should be rendered"""
         self._rect=rect
+        
     def _render_background(self):
         # xxx may have to prerender to a memdc when set theme is called for use on slow machines
         # takes 26ms on mijiti's machine!
@@ -149,6 +155,7 @@
             p.drawPixmap(self.background_offsetx,self.background_offsety, self.img)
         p.end()
         print "render background done"
+        
     def split_set_of_lines(self, lines):
 
         """Given a list of lines, decide how to split them best if they don't all fit on the screen
@@ -212,7 +219,6 @@
 
         return retval
 
-
     def _render_lines(self, lines):
         """render a set of lines according to the theme, return bounding box"""
         print "_render_lines", lines
@@ -234,6 +240,7 @@
         print "render lines DONE"
 
         return bbox
+        
     def _render_lines_unaligned(self, lines, tlcorner=(0,0)):
 
         """Given a list of lines to render, render each one in turn
@@ -265,7 +272,6 @@
 
         return  retval
 
-
     def _render_single_line(self, line, tlcorner=(0,0)):
 
         """render a single line of words onto the DC, top left corner
@@ -402,8 +408,3 @@
             p.drawText(x,y+metrics.height()-metrics.descent()-1, line)
         p.end()
         return (w, h)
-
-
-
-
-

=== modified file 'openlp/core/theme/theme.py'
--- openlp/core/theme/theme.py	2009-03-12 20:19:24 +0000
+++ openlp/core/theme/theme.py	2009-03-22 07:13:34 +0000
@@ -15,7 +15,8 @@
 '''<?xml version="1.0" encoding="iso-8859-1"?>
 <Theme>
   <Name>BlankStyle</Name>
-  <BackgroundType>0</BackgroundType>
+  <BackgroundMode>1</BackgroundMode>
+  <BackgroundType>0</BackgroundType>  
   <BackgroundParameter1>$000000</BackgroundParameter1>
   <BackgroundParameter2/>
   <BackgroundParameter3/>
@@ -37,6 +38,9 @@
         attributes:
           name : theme name
           
+           BackgroundMode   : 1 - Transparent
+                             1 - Opaque
+                             
           BackgroundType   : 0 - solid color
                              1 - gradient color
                              2 - image

=== modified file 'openlp/core/ui/__init__.py'
--- openlp/core/ui/__init__.py	2009-03-01 09:13:27 +0000
+++ openlp/core/ui/__init__.py	2009-03-22 07:11:05 +0000
@@ -27,7 +27,8 @@
 from alertform import AlertForm
 from settingsform import SettingsForm
 from servicemanager import ServiceManager
+from thememanager import ThemeManager
 from mainwindow import MainWindow
 
 __all__ = ['SplashScreen', 'AboutForm', 'SettingsForm',
-           'MainWindow', 'SlideController', 'ServiceManager']
+           'MainWindow', 'SlideController', 'ServiceManager', 'ThemeManager']

=== modified file 'openlp/core/ui/alertform.py'
--- openlp/core/ui/alertform.py	2009-03-01 09:13:27 +0000
+++ openlp/core/ui/alertform.py	2009-03-23 19:17:07 +0000
@@ -17,7 +17,7 @@
 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 Place, Suite 330, Boston, MA 02111-1307 USA
 """
-
+import logging
 from PyQt4 import QtCore, QtGui
 from PyQt4.QtGui import QDialog
 
@@ -25,14 +25,17 @@
 from openlp.core.resources import *
 
 class AlertForm(QDialog):
-
+    global log
+    log=logging.getLogger(u'AlertForm')
+    
     def __init__(self, parent=None):
         QDialog.__init__(self, parent)
         self.setupUi(self)
+        log.info(u'Defined')        
 
     def setupUi(self, AlertForm):
         AlertForm.setObjectName("AlertForm")
-        AlertForm.resize(370, 105)
+        AlertForm.resize(370, 110)
         icon = QtGui.QIcon()
         icon.addPixmap(QtGui.QPixmap(":/icon/openlp.org-icon-32.bmp"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
         AlertForm.setWindowIcon(icon)
@@ -56,7 +59,7 @@
         self.AlertEntryLabel.setSizePolicy(sizePolicy)
         self.AlertEntryLabel.setObjectName("AlertEntryLabel")
         self.AlertEntryEditItem = QtGui.QLineEdit(self.AlertEntryWidget)
-        self.AlertEntryEditItem.setGeometry(QtCore.QRect(0, 20, 353, 21))
+        self.AlertEntryEditItem.setGeometry(QtCore.QRect(0, 20, 353, 26))
         self.AlertEntryEditItem.setObjectName("AlertEntryEditItem")
         self.AlertFormLayout.addWidget(self.AlertEntryWidget)
         self.ButtonBoxWidget = QtGui.QWidget(AlertForm)
@@ -83,20 +86,21 @@
         self.retranslateUi(AlertForm)
         
         QtCore.QObject.connect(self.CancelButton, QtCore.SIGNAL("clicked()"), AlertForm.close)
+        QtCore.QObject.connect(self.DisplayButton, QtCore.SIGNAL("clicked()"), self.onDisplayClicked)
         QtCore.QMetaObject.connectSlotsByName(AlertForm)
 
     def retranslateUi(self, AlertForm):
-        AlertForm.setWindowTitle(translate("AlertForm", "Alert Message"))
-        self.AlertEntryLabel.setText(translate("AlertForm", "Alert Text:"))
-        self.DisplayButton.setText(translate("AlertForm", "Display"))
-        self.CancelButton.setText(translate("AlertForm", "Cancel"))
+        AlertForm.setWindowTitle(translate("AlertForm", u'Alert Message'))
+        self.AlertEntryLabel.setText(translate("AlertForm", u'Alert Text:'))
+        self.DisplayButton.setText(translate("AlertForm", u'Display'))
+        self.CancelButton.setText(translate("AlertForm", u'Cancel'))
 
-#    def show(self):
-#        self.AlertForm.show()
-        
         
     def load_settings(self):
         pass
         
     def save_settings(self):
         pass
+
+    def onDisplayClicked(self):
+        pass

=== modified file 'openlp/core/ui/mainwindow.py'
--- openlp/core/ui/mainwindow.py	2009-03-05 10:52:55 +0000
+++ openlp/core/ui/mainwindow.py	2009-03-23 19:17:07 +0000
@@ -3,7 +3,7 @@
 """
 OpenLP - Open Source Lyrics Projection
 Copyright (c) 2008 Raoul Snyman
-Portions copyright (c) 2008 Martin Thompson, Tim Bentley,
+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
@@ -18,54 +18,68 @@
 Place, Suite 330, Boston, MA 02111-1307 USA
 """
 import os
-
+import logging
 from time import sleep
+
 from PyQt4 import *
 from PyQt4 import QtCore, QtGui
 
 from openlp.core.resources import *
 
 from openlp.core.ui import AboutForm, SettingsForm, AlertForm, \
-                           SlideController, ServiceManager
-from openlp.core.lib import Plugin, MediaManagerItem, SettingsTab
+                           SlideController, ServiceManager, ThemeManager
+from openlp.core.lib import Plugin, MediaManagerItem, SettingsTab, EventManager
 
 from openlp.core import PluginManager
-import logging
+
 class MainWindow(object):
     global log
-    log=logging.getLogger("MainWindow")
-    log.info("MainWindow loaded")
+    log=logging.getLogger(u'MainWindow')
+    log.info(u'MainWindow loaded')
 
     def __init__(self):
         self.main_window = QtGui.QMainWindow()
+        self.EventManager = EventManager()        
         self.alert_form = AlertForm()
         self.about_form = AboutForm()
         self.settings_form = SettingsForm()
+        
         pluginpath = os.path.split(os.path.abspath(__file__))[0]
         pluginpath = os.path.abspath(os.path.join(pluginpath, '..', '..','plugins'))
         self.plugin_manager = PluginManager(pluginpath)
+        self.plugin_helpers = {}
+        
         self.setupUi()
 
-        log.info('')
-        self.plugin_manager.find_plugins(pluginpath, self.PreviewController, self.LiveController)
+        log.info(u'Load Plugins')
+        self.plugin_helpers[u'preview'] = self.PreviewController
+        self.plugin_helpers[u'live'] = self.LiveController
+        self.plugin_helpers[u'event'] = self.EventManager
+        self.plugin_helpers[u'theme'] = self.ThemeManagerContents  # Theme manger
+        
+        self.plugin_manager.find_plugins(pluginpath, self.plugin_helpers, self.EventManager)
         # hook methods have to happen after find_plugins.  Find plugins needs the controllers
         # hence the hooks have moved from setupUI() to here
 
         # Find and insert media manager items
-        log.info("hook media")
+        log.info(u'hook media')
         self.plugin_manager.hook_media_manager(self.MediaToolBox)
 
         # Find and insert settings tabs
-        log.info("hook settings")
+        log.info(u'hook settings')
         self.plugin_manager.hook_settings_tabs(self.settings_form)
 
         # Call the hook method to pull in import menus.
-        log.info("hook menus")
+        log.info(u'hook menus')
         self.plugin_manager.hook_import_menu(self.FileImportMenu)
 
         # Call the hook method to pull in export menus.
-        self.plugin_manager.hook_import_menu(self.FileExportMenu)
+        self.plugin_manager.hook_export_menu(self.FileExportMenu)
 
+        # Call the initialise method to setup plugins.
+        log.info(u'initialise plugins')        
+        self.plugin_manager.initialise_plugins()
+        
     def setupUi(self):
         self.main_window.setObjectName("main_window")
         self.main_window.resize(1087, 847)
@@ -151,7 +165,7 @@
         self.MediaManagerLayout.addWidget(self.MediaToolBox)
         self.MediaManagerDock.setWidget(self.MediaManagerContents)
         self.main_window.addDockWidget(QtCore.Qt.DockWidgetArea(1), self.MediaManagerDock)
-
+        #Sevice Manager Defined
         self.ServiceManagerDock = QtGui.QDockWidget(self.main_window)
         ServiceManagerIcon = QtGui.QIcon()
         ServiceManagerIcon.addPixmap(QtGui.QPixmap(":/system/system_servicemanager.png"),
@@ -162,6 +176,7 @@
         self.ServiceManagerContents = ServiceManager(self)
         self.ServiceManagerDock.setWidget(self.ServiceManagerContents)
         self.main_window.addDockWidget(QtCore.Qt.DockWidgetArea(2), self.ServiceManagerDock)
+        #Theme Manager Defined        
         self.ThemeManagerDock = QtGui.QDockWidget(self.main_window)
         ThemeManagerIcon = QtGui.QIcon()
         ThemeManagerIcon.addPixmap(QtGui.QPixmap(":/system/system_thememanager.png"),
@@ -169,41 +184,46 @@
         self.ThemeManagerDock.setWindowIcon(ThemeManagerIcon)
         self.ThemeManagerDock.setFloating(False)
         self.ThemeManagerDock.setObjectName("ThemeManagerDock")
-        self.ThemeManagerContents = QtGui.QWidget()
-        self.ThemeManagerContents.setObjectName("ThemeManagerContents")
-        self.ThemeManagerLayout = QtGui.QVBoxLayout(self.ThemeManagerContents)
-        self.ThemeManagerLayout.setSpacing(0)
-        self.ThemeManagerLayout.setMargin(0)
-        self.ThemeManagerLayout.setObjectName("ThemeManagerLayout")
-        self.ThemeManagerToolbar = QtGui.QToolBar(self.ThemeManagerContents)
-        self.ThemeManagerToolbar.setObjectName("ThemeManagerToolbar")
-        NewThemeIcon = QtGui.QIcon()
-        NewThemeIcon.addPixmap(QtGui.QPixmap(":/themes/theme_new.png"),
-            QtGui.QIcon.Normal, QtGui.QIcon.Off)
-        self.ThemeNewItem = self.ThemeManagerToolbar.addAction(NewThemeIcon, 'New theme')
-        EditThemeIcon = QtGui.QIcon()
-        EditThemeIcon.addPixmap(QtGui.QPixmap(":/themes/theme_edit.png"),
-            QtGui.QIcon.Normal, QtGui.QIcon.Off)
-        self.ThemeEditItem = self.ThemeManagerToolbar.addAction(EditThemeIcon, 'Edit theme')
-        DeleteThemeIcon = QtGui.QIcon()
-        DeleteThemeIcon.addPixmap(QtGui.QPixmap(":/themes/theme_delete.png"),
-            QtGui.QIcon.Normal, QtGui.QIcon.Off)
-        self.ThemeDeleteButton = self.ThemeManagerToolbar.addAction(DeleteThemeIcon, 'Delete theme')
-        self.ThemeManagerToolbar.addSeparator()
-        ImportThemeIcon = QtGui.QIcon()
-        ImportThemeIcon.addPixmap(QtGui.QPixmap(":/themes/theme_import.png"),
-            QtGui.QIcon.Normal, QtGui.QIcon.Off)
-        self.ThemeImportButton = self.ThemeManagerToolbar.addAction(ImportThemeIcon, 'Import theme')
-        ExportThemeIcon = QtGui.QIcon()
-        ExportThemeIcon.addPixmap(QtGui.QPixmap(":/themes/theme_export.png"),
-            QtGui.QIcon.Normal, QtGui.QIcon.Off)
-        self.ThemeExportButton = self.ThemeManagerToolbar.addAction(ExportThemeIcon, 'Export theme')
-        self.ThemeManagerLayout.addWidget(self.ThemeManagerToolbar)
-        self.ThemeManagerListView = QtGui.QListView(self.ThemeManagerContents)
-        self.ThemeManagerListView.setObjectName("ThemeManagerListView")
-        self.ThemeManagerLayout.addWidget(self.ThemeManagerListView)
+        
+        self.ThemeManagerContents = ThemeManager(self)        
+        
+#        self.ThemeManagerContents = QtGui.QWidget()
+#        self.ThemeManagerContents.setObjectName("ThemeManagerContents")
+#        self.ThemeManagerLayout = QtGui.QVBoxLayout(self.ThemeManagerContents)
+#        self.ThemeManagerLayout.setSpacing(0)
+#        self.ThemeManagerLayout.setMargin(0)
+#        self.ThemeManagerLayout.setObjectName("ThemeManagerLayout")
+#        self.ThemeManagerToolbar = QtGui.QToolBar(self.ThemeManagerContents)
+#        self.ThemeManagerToolbar.setObjectName("ThemeManagerToolbar")
+#        NewThemeIcon = QtGui.QIcon()
+#        NewThemeIcon.addPixmap(QtGui.QPixmap(":/themes/theme_new.png"),
+#            QtGui.QIcon.Normal, QtGui.QIcon.Off)
+#        self.ThemeNewItem = self.ThemeManagerToolbar.addAction(NewThemeIcon, 'New theme')
+#        EditThemeIcon = QtGui.QIcon()
+#        EditThemeIcon.addPixmap(QtGui.QPixmap(":/themes/theme_edit.png"),
+#            QtGui.QIcon.Normal, QtGui.QIcon.Off)
+#        self.ThemeEditItem = self.ThemeManagerToolbar.addAction(EditThemeIcon, 'Edit theme')
+#        DeleteThemeIcon = QtGui.QIcon()
+#        DeleteThemeIcon.addPixmap(QtGui.QPixmap(":/themes/theme_delete.png"),
+#            QtGui.QIcon.Normal, QtGui.QIcon.Off)
+#        self.ThemeDeleteButton = self.ThemeManagerToolbar.addAction(DeleteThemeIcon, 'Delete theme')
+#        self.ThemeManagerToolbar.addSeparator()
+#        ImportThemeIcon = QtGui.QIcon()
+#        ImportThemeIcon.addPixmap(QtGui.QPixmap(":/themes/theme_import.png"),
+#            QtGui.QIcon.Normal, QtGui.QIcon.Off)
+#        self.ThemeImportButton = self.ThemeManagerToolbar.addAction(ImportThemeIcon, 'Import theme')
+#        ExportThemeIcon = QtGui.QIcon()
+#        ExportThemeIcon.addPixmap(QtGui.QPixmap(":/themes/theme_export.png"),
+#            QtGui.QIcon.Normal, QtGui.QIcon.Off)
+#        self.ThemeExportButton = self.ThemeManagerToolbar.addAction(ExportThemeIcon, 'Export theme')
+#        self.ThemeManagerLayout.addWidget(self.ThemeManagerToolbar)
+#        self.ThemeManagerListView = QtGui.QListView(self.ThemeManagerContents)
+#        self.ThemeManagerListView.setObjectName("ThemeManagerListView")
+#        self.ThemeManagerLayout.addWidget(self.ThemeManagerListView)
+
         self.ThemeManagerDock.setWidget(self.ThemeManagerContents)
         self.main_window.addDockWidget(QtCore.Qt.DockWidgetArea(2), self.ThemeManagerDock)
+        
         self.FileNewItem = QtGui.QAction(self.main_window)
         self.FileNewItem.setIcon(self.ServiceManagerContents.Toolbar.getIconFromTitle("New Service"))
         self.FileNewItem.setObjectName("FileNewItem")
@@ -359,11 +379,11 @@
 #         self.ServiceManagerContents.ThemeComboBox.setItemText(1, QtGui.QApplication.translate("main_window", "Snowy Mountains", None, QtGui.QApplication.UnicodeUTF8))
 #         self.ServiceManagerContents.ThemeComboBox.setItemText(2, QtGui.QApplication.translate("main_window", "Wilderness", None, QtGui.QApplication.UnicodeUTF8))
         self.ThemeManagerDock.setWindowTitle(QtGui.QApplication.translate("main_window", "Theme Manager", None, QtGui.QApplication.UnicodeUTF8))
-        self.ThemeNewItem.setText(QtGui.QApplication.translate("main_window", "New Theme", None, QtGui.QApplication.UnicodeUTF8))
-        self.ThemeEditItem.setText(QtGui.QApplication.translate("main_window", "Edit Theme", None, QtGui.QApplication.UnicodeUTF8))
-        self.ThemeDeleteButton.setText(QtGui.QApplication.translate("main_window", "Delete Theme", None, QtGui.QApplication.UnicodeUTF8))
-        self.ThemeImportButton.setText(QtGui.QApplication.translate("main_window", "Import Theme", None, QtGui.QApplication.UnicodeUTF8))
-        self.ThemeExportButton.setText(QtGui.QApplication.translate("main_window", "Export Theme", None, QtGui.QApplication.UnicodeUTF8))
+#        self.ThemeNewItem.setText(QtGui.QApplication.translate("main_window", "New Theme", None, QtGui.QApplication.UnicodeUTF8))
+#        self.ThemeEditItem.setText(QtGui.QApplication.translate("main_window", "Edit Theme", None, QtGui.QApplication.UnicodeUTF8))
+#        self.ThemeDeleteButton.setText(QtGui.QApplication.translate("main_window", "Delete Theme", None, QtGui.QApplication.UnicodeUTF8))
+#        self.ThemeImportButton.setText(QtGui.QApplication.translate("main_window", "Import Theme", None, QtGui.QApplication.UnicodeUTF8))
+#        self.ThemeExportButton.setText(QtGui.QApplication.translate("main_window", "Export Theme", None, QtGui.QApplication.UnicodeUTF8))
         self.FileNewItem.setText(QtGui.QApplication.translate("main_window", "&New", None, QtGui.QApplication.UnicodeUTF8))
         self.FileNewItem.setToolTip(QtGui.QApplication.translate("main_window", "New Service", None, QtGui.QApplication.UnicodeUTF8))
         self.FileNewItem.setStatusTip(QtGui.QApplication.translate("main_window", "Create a new Service", None, QtGui.QApplication.UnicodeUTF8))

=== modified file 'openlp/core/ui/servicemanager.py'
--- openlp/core/ui/servicemanager.py	2009-03-04 21:56:27 +0000
+++ openlp/core/ui/servicemanager.py	2009-03-23 19:17:07 +0000
@@ -40,7 +40,7 @@
     Root contains a list of ServiceItems
     """
     global log
-    log=logging.getLogger("ServiceData")
+    log=logging.getLogger(u'ServiceData')
     def __init__(self):
         QAbstractItemModel.__init__(self)
         self.items=[]
@@ -108,6 +108,8 @@
     one lump.
     Also handles the UI tasks of moving things up and down etc.
     """
+    global log
+    log=logging.getLogger(u'ServiceManager')    
 
     def __init__(self, parent):
         QWidget.__init__(self)
@@ -163,6 +165,7 @@
                 self.service_data.addRow(item)
             else:
                 self.service_data.insertRow(row+1, item)
+                
     def removeServiceItem(self):
         """Remove currently selected item"""
         pass

=== modified file 'openlp/core/ui/settingsform.py'
--- openlp/core/ui/settingsform.py	2009-03-05 20:31:17 +0000
+++ openlp/core/ui/settingsform.py	2009-03-23 19:17:07 +0000
@@ -40,9 +40,9 @@
         # Themes tab
         self.ThemesTab = ThemesTab()
         self.addTab(self.ThemesTab)
-        # Alerts tab
+        # Alert tab
         self.AlertsTab = AlertsTab()
-        self.addTab(self.AlertsTab)
+        self.addTab(self.AlertsTab)        
 
     def addTab(self, tab):
         log.info(u'Inserting %s' % tab.title())

=== added file 'openlp/core/ui/thememanager.py'
--- openlp/core/ui/thememanager.py	1970-01-01 00:00:00 +0000
+++ openlp/core/ui/thememanager.py	2009-03-23 20:18:06 +0000
@@ -0,0 +1,191 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
+"""
+OpenLP - Open Source Lyrics Projection
+Copyright (c) 2009 Raoul Snyman
+Portions copyright (c) 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 os
+
+from time import sleep
+from copy import deepcopy
+from PyQt4 import *
+from PyQt4 import QtCore, QtGui
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+# from openlp.core.resources import *
+# from openlp.core.ui import AboutForm, AlertForm, SettingsForm, SlideController
+from openlp.core.lib import OpenLPToolbar
+#from openlp.core.lib import ThemeItem
+
+# from openlp.core import PluginManager
+import logging
+
+class ThemeData(QAbstractItemModel):
+    """
+    Tree of items for an order of Theme.
+    Includes methods for reading and writing the contents to an OOS file
+    Root contains a list of ThemeItems
+    """
+    global log
+    log=logging.getLogger(u'ThemeData')
+    def __init__(self):
+        QAbstractItemModel.__init__(self)
+        self.items=[]
+        log.info("Starting")
+    def columnCount(self, parent):
+        return 1; # always only a single column (for now)
+    def rowCount(self, parent):
+        return len(self.items)
+    def insertRow(self, row, Theme_item):
+#         self.beginInsertRows(QModelIndex(),row,row)
+        log.info("insert row %d:%s"%(row,Theme_item))
+        self.items.insert(row, Theme_item)
+        log.info("Items: %s" % self.items)
+#         self.endInsertRows()
+    def removeRow(self, row):
+        self.beginRemoveRows(QModelIndex(), row,row)
+        self.items.pop(row)
+        self.endRemoveRows()
+    def addRow(self, item):
+        self.insertRow(len(self.items), item)
+        
+    def index(self, row, col, parent = QModelIndex()):
+        return self.createIndex(row,col)
+
+    def parent(self, index=QModelIndex()):
+        return QModelIndex() # no children as yet
+    def data(self, index, role):
+        """
+        Called by the Theme manager to draw us in the Theme window
+        """
+        row=index.row()
+        if row > len(self.items): # if the last row is selected and deleted, we then get called with an empty row!
+            return QVariant()
+        item=self.items[row]
+        if role==Qt.DisplayRole:
+            retval= item.pluginname + ":" + item.shortname
+        elif role == Qt.DecorationRole:
+            retval = item.iconic_representation
+        elif role == Qt.ToolTipRole:
+            retval= None
+        else:
+            retval= None
+        if retval == None:
+            retval=QVariant()
+#         log.info("Returning"+ str(retval))
+        if type(retval) is not type(QVariant):
+            return QVariant(retval)
+        else:
+            return retval
+        
+    def __iter__(self):
+        for i in self.items:
+            yield i
+
+    def item(self, row):
+        log.info("Get Item:%d -> %s" %(row, str(self.items)))
+        return self.items[row]
+
+    
+class ThemeManager(QWidget):
+
+    """Manages the orders of Theme.  Currently this involves taking
+    text strings from plugins and adding them to an OOS file. In
+    future, it will also handle zipping up all the resources used into
+    one lump.
+    Also handles the UI tasks of moving things up and down etc.
+    """
+    global log
+    log=logging.getLogger(u'ThemeManager')
+
+    def __init__(self, parent):
+        QWidget.__init__(self)
+        self.parent=parent
+        self.Layout = QtGui.QVBoxLayout(self)
+        self.Layout.setSpacing(0)
+        self.Layout.setMargin(0)
+        self.Toolbar = OpenLPToolbar(self)
+        self.Toolbar.addToolbarButton("New Theme", ":/themes/theme_new.png")
+        self.Toolbar.addToolbarButton("Edit Theme", ":/themes/theme_edit.png")
+        self.Toolbar.addToolbarButton("Delete Theme", ":/themes/theme_delete.png")
+        self.Toolbar.addSeparator()
+        self.Toolbar.addToolbarButton("Import Theme", ":/themes/theme_import.png")
+        self.Toolbar.addToolbarButton("Export Theme", ":/themes/theme_export.png")        
+        self.ThemeWidget = QtGui.QWidgetAction(self.Toolbar)
+        self.Toolbar.addAction(self.ThemeWidget)
+
+        self.Layout.addWidget(self.Toolbar)
+
+        self.TreeView = QtGui.QTreeView(self)
+        self.Theme_data=ThemeData()
+        self.TreeView.setModel(self.Theme_data)
+        self.Layout.addWidget(self.TreeView)
+        self.themelist= []
+        
+#    def addThemeItem(self, item):
+#        """Adds Theme item"""
+#        log.info("addThemeItem")
+#        indexes=self.TreeView.selectedIndexes()
+#        assert len(indexes) <= 1 # can only have one selected index in this view
+#        if indexes == []:
+#            log.info("No row")
+#            row = None
+#            selected_item = None
+#        else:
+#            row=indexes[0].row()
+#            # if currently selected is of correct type, add it to it
+#            log.info("row:%d"%row)
+#            selected_item=self.Theme_data.item(row)
+#        if type(selected_item) == type(item):
+#            log.info("Add to existing item")
+#            selected_item.add(item)
+#        else:
+#            log.info("Create new item")
+#            if row is None:
+#                self.Theme_data.addRow(item)
+#            else:
+#                self.Theme_data.insertRow(row+1, item)
+#                
+#    def removeThemeItem(self):
+#        """Remove currently selected item"""
+#        pass
+#
+#    def oos_as_text(self):
+#        text=[]
+#        log.info( "oos as text")
+#        log.info("Data:"+str(self.Theme_data))
+#        for i in self.Theme_data:
+#            text.append("# " + str(i))
+#            text.append(i.get_oos_text())
+#        return '\n'.join(text)
+#
+#    def write_oos(self, filename):
+#        """
+#        Write a full OOS file out - iterate over plugins and call their respective methods
+#        This format is totally arbitrary testing purposes - something sensible needs to go in here!
+#        """
+#        oosfile=open(filename, "w")
+#        oosfile.write("# BEGIN OOS\n")
+#        oosfile.write(self.oos_as_text)
+#        oosfile.write("# END OOS\n")
+#        oosfile.close()
+        
+    def load(self):
+        log.debug(u'Load')        
+        self.themelist = [u'African Sunset', u'Snowy Mountains', u'Wilderness', u'Wet and Windy London']
+        
+    def getThemes(self):
+        return self.themelist

=== modified file 'openlp/plugins/bibles/bibleplugin.py'
--- openlp/plugins/bibles/bibleplugin.py	2009-03-18 17:19:30 +0000
+++ openlp/plugins/bibles/bibleplugin.py	2009-03-22 07:13:34 +0000
@@ -35,9 +35,9 @@
     log=logging.getLogger(u'BiblePlugin')
     log.info(u'Bible Plugin loaded')
 
-    def __init__(self):
+    def __init__(self, plugin_helpers):
         # Call the parent constructor
-        Plugin.__init__(self, u'Bibles', u'1.9.0')
+        Plugin.__init__(self, u'Bibles', u'1.9.0', plugin_helpers)
         self.weight = -9
         # Create the plugin icon
         self.icon = QtGui.QIcon()

=== modified file 'openlp/plugins/custom/customplugin.py'
--- openlp/plugins/custom/customplugin.py	2009-03-17 05:05:04 +0000
+++ openlp/plugins/custom/customplugin.py	2009-03-25 20:30:48 +0000
@@ -22,7 +22,7 @@
 from PyQt4 import QtCore, QtGui
 
 from openlp.core.resources import *
-from openlp.core.lib import Plugin
+from openlp.core.lib import Plugin, Event
 from forms import EditCustomForm
 from openlp.plugins.custom.lib import CustomManager, CustomTab, CustomMediaItem, CustomServiceItem
 
@@ -31,10 +31,10 @@
     global log
     log=logging.getLogger(u'CustomPlugin')
     log.info(u'Custom Plugin loaded')
-
-    def __init__(self, preview_controller, live_controller):
+    
+    def __init__(self, plugin_helpers):
         # Call the parent constructor
-        Plugin.__init__(self, u'Custom', u'1.9.0',  preview_controller, live_controller)
+        Plugin.__init__(self, u'Custom', u'1.9.0', plugin_helpers)
         self.weight = -5
         self.custommanager = CustomManager(self.config)
         self.edit_custom_form = EditCustomForm(self.custommanager)
@@ -42,18 +42,16 @@
         self.icon = QtGui.QIcon()
         self.icon.addPixmap(QtGui.QPixmap(':/media/media_custom.png'),
             QtGui.QIcon.Normal, QtGui.QIcon.Off)
-            
-        self.preview_service_item = CustomServiceItem(preview_controller)
-        self.live_service_item = CustomServiceItem(live_controller)            
+        self.preview_service_item = CustomServiceItem(self.preview_controller)
+        self.live_service_item = CustomServiceItem(self.live_controller)
 
     def get_media_manager_item(self):
         # Create the CustomManagerItem object
         self.media_item = CustomMediaItem(self, self.icon, u'Custom Slides')
         return self.media_item
        
-    def get_settings_tab(self):
-        pass
-
-    def initialise(self):
-        pass
-
+    def handle_event(self, event):
+        """
+        Handle the event contained in the event object.
+        """
+        log.debug(u'Handle event called with event %s' %event.get_type())

=== modified file 'openlp/plugins/custom/forms/editcustomform.py'
--- openlp/plugins/custom/forms/editcustomform.py	2009-03-14 08:11:25 +0000
+++ openlp/plugins/custom/forms/editcustomform.py	2009-03-25 20:30:48 +0000
@@ -32,6 +32,7 @@
         Constructor
         """
         QtGui.QDialog.__init__(self, parent)
+        #self.parent = parent 
         self.setupUi(self)
         # Connecting signals and slots
         QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"), self.rejected)
@@ -52,8 +53,7 @@
         # Create other objects and forms
         self.custommanager = custommanager
         self.initialise()
-        self.VerseListView.setAlternatingRowColors(True)
-        #self.savebutton = self.ButtonBox.button(QtGui.QDialogButtonBox.Save)
+        self.VerseListView.setAlternatingRowColors(True)        
         
     def initialise(self):
         self.valid = True
@@ -65,7 +65,9 @@
         self.VerseTextEdit.clear()
         self.VerseListView.clear()
         #make sure we have a new item 
-        self.customSlide = CustomSlide()    
+        self.customSlide = CustomSlide()
+        self.ThemecomboBox.addItem(u'')
+        #self.theme_manager.getThemes()
 
     def loadCustom(self, id):
         self.customSlide = CustomSlide()

=== modified file 'openlp/plugins/images/imageplugin.py'
--- openlp/plugins/images/imageplugin.py	2009-03-18 17:19:30 +0000
+++ openlp/plugins/images/imageplugin.py	2009-03-22 07:13:34 +0000
@@ -31,17 +31,17 @@
     log=logging.getLogger(u'ImagePlugin')
     log.info(u'Image Plugin loaded')
 
-    def __init__(self, preview_controller, live_controller):
+    def __init__(self, plugin_helpers):
         # Call the parent constructor
-        Plugin.__init__(self, u'Images', u'1.9.0', preview_controller, live_controller)
+        Plugin.__init__(self, u'Images', u'1.9.0', plugin_helpers)
         self.weight = -7
         # Create the plugin icon
         self.icon = QtGui.QIcon()
         self.icon.addPixmap(QtGui.QPixmap(':/media/media_image.png'),
             QtGui.QIcon.Normal, QtGui.QIcon.Off)
 
-        self.preview_service_item = ImageServiceItem(preview_controller)
-        self.live_service_item = ImageServiceItem(live_controller)
+        self.preview_service_item = ImageServiceItem(self.preview_controller)
+        self.live_service_item = ImageServiceItem(self.live_controller)
 
     def get_media_manager_item(self):
         # Create the MediaManagerItem object

=== modified file 'openlp/plugins/images/lib/__init__.py'
--- openlp/plugins/images/lib/__init__.py	2009-03-08 12:41:07 +0000
+++ openlp/plugins/images/lib/__init__.py	2009-03-24 06:07:03 +0000
@@ -17,6 +17,6 @@
 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 Place, Suite 330, Boston, MA 02111-1307 USA
 """
+from listwithpreviews import ListWithPreviews
 from imageserviceitem import ImageServiceItem
-from listwithpreviews import ListWithPreviews
 from mediaitem import ImageMediaItem

=== modified file 'openlp/plugins/presentations/presentationplugin.py'
--- openlp/plugins/presentations/presentationplugin.py	2009-03-19 17:31:33 +0000
+++ openlp/plugins/presentations/presentationplugin.py	2009-03-22 07:13:34 +0000
@@ -28,9 +28,9 @@
 
 class PresentationPlugin(Plugin):
 
-    def __init__(self):
+    def __init__(self, plugin_helpers):
         # Call the parent constructor
-        Plugin.__init__(self, u'Presentations', u'1.9.0')
+        Plugin.__init__(self, u'Presentations', u'1.9.0', plugin_helpers)
         self.weight = -8
         # Create the plugin icon
         self.icon = QtGui.QIcon()

=== modified file 'openlp/plugins/songs/songsplugin.py'
--- openlp/plugins/songs/songsplugin.py	2009-03-18 17:19:30 +0000
+++ openlp/plugins/songs/songsplugin.py	2009-03-22 07:13:34 +0000
@@ -33,9 +33,9 @@
     log=logging.getLogger(u'SongsPlugin')
     log.info(u'Song Plugin loaded')
 
-    def __init__(self):
+    def __init__(self, plugin_helpers):
         # Call the parent constructor
-        Plugin.__init__(self, u'Songs', u'1.9.0')
+        Plugin.__init__(self, u'Songs', u'1.9.0', plugin_helpers)
         self.weight = -10
         self.songmanager = SongManager(self.config)
         self.openlp_import_form = OpenLPImportForm()

=== modified file 'openlp/plugins/videos/videoplugin.py'
--- openlp/plugins/videos/videoplugin.py	2009-03-19 17:31:33 +0000
+++ openlp/plugins/videos/videoplugin.py	2009-03-22 07:13:34 +0000
@@ -26,9 +26,9 @@
 
 class VideoPlugin(Plugin):
 
-    def __init__(self):
+    def __init__(self, plugin_helpers):
         # Call the parent constructor
-        Plugin.__init__(self, u'Videos', u'1.9.0')
+        Plugin.__init__(self, u'Videos', u'1.9.0', plugin_helpers)
         self.weight = -6
         # Create the plugin icon
         self.icon = QtGui.QIcon()


Follow ups