← Back to team overview

openlp-core team mailing list archive

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

 

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

    Requested reviews:
    Tim Bentley (trb143)

-- 
https://code.launchpad.net/~trb143/openlp/songediting/+merge/15368
Your team OpenLP Core is subscribed to branch lp:openlp.
=== modified file 'openlp/core/lib/plugin.py'
--- openlp/core/lib/plugin.py	2009-11-07 07:42:18 +0000
+++ openlp/core/lib/plugin.py	2009-11-29 18:25:21 +0000
@@ -31,9 +31,9 @@
     """
     Defines the status of the plugin
     """
-    Active = 0
-    Inactive = 1
-    Disabled = 2
+    Active = 1
+    Inactive = 0
+    Disabled = -1
 
 class Plugin(QtCore.QObject):
     """

=== modified file 'openlp/core/lib/renderer.py'
--- openlp/core/lib/renderer.py	2009-11-24 19:10:54 +0000
+++ openlp/core/lib/renderer.py	2009-11-29 18:25:21 +0000
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+    # -*- coding: utf-8 -*-
 # vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
 
 ###############################################################################
@@ -49,6 +49,7 @@
         self._theme = None
         self._bg_image_filename = None
         self._frame = None
+        self._frameOp = None
         self.bg_frame = None
         self.bg_image = None
 
@@ -134,6 +135,8 @@
             frame_height)
         self._frame = QtGui.QImage(frame_width, frame_height,
             QtGui.QImage.Format_ARGB32_Premultiplied)
+        self._frameOp = QtGui.QImage(frame_width, frame_height,
+            QtGui.QImage.Format_ARGB32_Premultiplied)
         if self._bg_image_filename and not self.bg_image:
             self.scale_bg_image()
         if self.bg_frame is None:
@@ -255,13 +258,14 @@
             bbox1 = self._render_lines_unaligned(footer_lines, True)
         # reset the frame. first time do not worry about what you paint on.
         self._frame = QtGui.QImage(self.bg_frame)
+        self._frameOp = QtGui.QImage(self.bg_frame)
         x, y = self._correctAlignment(self._rect, bbox)
         bbox = self._render_lines_unaligned(lines, False, (x, y), True)
         if footer_lines:
             bbox = self._render_lines_unaligned(footer_lines, True,
                 (self._rect_footer.left(), self._rect_footer.top()), True)
         log.debug(u'generate_frame_from_lines - Finish')
-        return self._frame
+        return {u'main':self._frame, u'trans':self._frameOp}
 
     def _generate_background_frame(self):
         """
@@ -569,6 +573,22 @@
         if draw:
             painter.drawText(x, y + metrics.ascent(), line)
         painter.end()
+        # Print 2nd image with 50% weight
+        painter = QtGui.QPainter()
+        painter.begin(self._frameOp)
+        painter.setRenderHint(QtGui.QPainter.Antialiasing);
+        painter.setOpacity(0.5)
+        painter.setFont(font)
+        if color is None:
+            if footer:
+                painter.setPen(QtGui.QColor(self._theme.font_footer_color))
+            else:
+                painter.setPen(QtGui.QColor(self._theme.font_main_color))
+        else:
+            painter.setPen(QtGui.QColor(color))
+        if draw:
+            painter.drawText(x, y + metrics.ascent(), line)
+        painter.end()
         return (w, h)
 
     def snoop_Image(self, image, image2=None):

=== modified file 'openlp/core/lib/serviceitem.py'
--- openlp/core/lib/serviceitem.py	2009-11-15 16:57:11 +0000
+++ openlp/core/lib/serviceitem.py	2009-11-29 18:25:21 +0000
@@ -104,7 +104,8 @@
                     for line in format:
                         lines += line + u'\n'
                     title = lines.split(u'\n')[0]
-                    self._display_frames.append({u'title': title, u'text': lines})
+                    self._display_frames.append({u'title': title, \
+                        u'text': lines, u'verseTag': slide[u'verseTag'] })
                 log.log(15, u'Formatting took %4s' % (time.time() - before))
         elif self.service_item_type == ServiceItemType.Image:
             for slide in self._raw_frames:
@@ -147,7 +148,7 @@
         self._raw_frames.append(
             {u'title': title, u'image': image})
 
-    def add_from_text(self, title, raw_slide):
+    def add_from_text(self, title, raw_slide, verseTag=None):
         """
         Add a text slide to the service item.
 
@@ -160,7 +161,7 @@
         self.service_item_type = ServiceItemType.Text
         title = title.split(u'\n')[0]
         self._raw_frames.append(
-            {u'title': title, u'raw_slide': raw_slide})
+            {u'title': title, u'raw_slide': raw_slide, u'verseTag':verseTag})
 
     def add_from_command(self, path, file_name, image):
         """

=== modified file 'openlp/core/ui/maindisplay.py'
--- openlp/core/ui/maindisplay.py	2009-11-15 07:02:27 +0000
+++ openlp/core/ui/maindisplay.py	2009-11-29 18:25:21 +0000
@@ -24,6 +24,7 @@
 
 import logging
 import os
+import time
 
 from PyQt4 import QtCore, QtGui
 from PyQt4.phonon import Phonon
@@ -110,6 +111,7 @@
         self.timer_id = 0
         self.firstTime = True
         self.mediaLoaded = False
+        self.hasTransition = False
         QtCore.QObject.connect(Receiver.get_receiver(),
             QtCore.SIGNAL(u'alert_text'), self.displayAlert)
         QtCore.QObject.connect(Receiver.get_receiver(),
@@ -127,6 +129,7 @@
         QtCore.QObject.connect(Receiver.get_receiver(),
             QtCore.SIGNAL(u'media_stop'), self.onMediaStop)
 
+
     def setup(self, screenNumber):
         """
         Sets up the screen on a particular screen.
@@ -183,27 +186,34 @@
         if not self.primary:
             self.setVisible(True)
 
-    def frameView(self, frame):
+    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
         """
-        self.frame = frame
         if self.timer_id != 0 :
             self.displayAlert()
         elif not self.displayBlank:
-#            self.setWindowOpacity(0.5)
-#            self.show()
-            self.display.setPixmap(QtGui.QPixmap.fromImage(frame))
-#            QtCore.QTimer.singleShot(500, self.aa )
+            if transition:
+                if self.hasTransition:
+                    delay = 0.01
+                    self.display.setPixmap(QtGui.QPixmap.fromImage(self.frame[u'trans']))
+                    self.repaint()
+                    time.sleep(delay)
+                    self.display.setPixmap(QtGui.QPixmap.fromImage(frame[u'trans']))
+                    self.repaint()
+                    time.sleep(delay)
+                self.hasTransition = True
+                self.display.setPixmap(QtGui.QPixmap.fromImage(frame[u'main']))
+                self.repaint()
+            else:
+                self.display.setPixmap(QtGui.QPixmap.fromImage(frame))
             if not self.isVisible():
                 self.setVisible(True)
                 self.showFullScreen()
-#
-#    def aa(self):
-#        self.setWindowOpacity(1)
+        self.frame = frame
 
     def blankDisplay(self, blanked=True):
         if blanked:

=== modified file 'openlp/core/ui/pluginform.py'
--- openlp/core/ui/pluginform.py	2009-11-07 14:58:24 +0000
+++ openlp/core/ui/pluginform.py	2009-11-29 18:25:21 +0000
@@ -86,7 +86,10 @@
         self.VersionNumberLabel.setText(self.activePlugin.version)
         self.AboutTextBrowser.setHtml(self.activePlugin.about())
         self.programaticChange = True
-        self.StatusComboBox.setCurrentIndex(int(self.activePlugin.status))
+        status = 1
+        if self.activePlugin.status == PluginStatus.Active:
+            status = 0
+        self.StatusComboBox.setCurrentIndex(status)
         self.StatusComboBox.setEnabled(True)
         self.programaticChange = False
 
@@ -108,10 +111,11 @@
     def onStatusComboBoxChanged(self, status):
         if self.programaticChange:
             return
-        self.activePlugin.toggle_status(status)
-        if status == PluginStatus.Active:
+        if status == 0:
+            self.activePlugin.toggle_status(PluginStatus.Active)
             self.activePlugin.initialise()
         else:
+            self.activePlugin.toggle_status(PluginStatus.Inactive)
             self.activePlugin.finalise()
         status_text = 'Inactive'
         if self.activePlugin.status == PluginStatus.Active:

=== modified file 'openlp/core/ui/servicemanager.py'
--- openlp/core/ui/servicemanager.py	2009-11-15 07:24:30 +0000
+++ openlp/core/ui/servicemanager.py	2009-11-29 18:25:21 +0000
@@ -433,9 +433,9 @@
                         {u'serviceitem':item[u'service_item'].get_service_repr()})
                     if item[u'service_item'].service_item_type == ServiceItemType.Image or \
                         item[u'service_item'].service_item_type == ServiceItemType.Command:
-                        for frame in item[u'service_item'].frames:
+                        for frame in item[u'service_item'].get_frames:
                             path_from = unicode(os.path.join(
-                                item[u'service_item'].service_item_path, frame[u'title']))
+                                item[u'service_item'].service_item_path, frame.get_frame_title()))
                             zip.write(path_from)
                 file = open(servicefile, u'wb')
                 cPickle.dump(service, file)

=== modified file 'openlp/core/ui/slidecontroller.py'
--- openlp/core/ui/slidecontroller.py	2009-11-15 07:24:30 +0000
+++ openlp/core/ui/slidecontroller.py	2009-11-29 18:25:21 +0000
@@ -89,6 +89,7 @@
         self.selectedRow = 0
         self.serviceItem = None
         self.Panel = QtGui.QWidget(parent.ControlSplitter)
+        self.slideList = {}
         # Layout for holding panel
         self.PanelLayout = QtGui.QVBoxLayout(self.Panel)
         self.PanelLayout.setSpacing(0)
@@ -352,14 +353,14 @@
                     self.Songbar.actions[action].setVisible(False)
                 if item.verse_order:
                     verses = item.verse_order.split(u' ')
-                    for verse in verses:
-                        if not verse or int(verse) > 12:
-                            break
-                        try:
-                            self.Songbar.actions[verse].setVisible(True)
-                        except:
-                            #More than 20 verses hard luck
-                            pass
+#                    for verse in verses:
+#                        if not verse or int(verse) > 12:
+#                            break
+#                        try:
+#                            self.Songbar.actions[verse].setVisible(True)
+#                        except:
+#                            #More than 20 verses hard luck
+#                            pass
                     self.Songbar.setVisible(True)
         elif item.is_image():
             #Not sensible to allow loops with 1 frame
@@ -416,7 +417,6 @@
         #If old item was a command tell it to stop
         if self.serviceItem and self.serviceItem.is_command():
             self.onMediaStop()
-        self.enableToolBar(item)
         if item.is_command():
             if self.isLive:
                 Receiver.send_message(u'%s_start' % item.name.lower(), \
@@ -427,17 +427,18 @@
                     self.onMediaStart(item)
         self.displayServiceManagerItems(item, slideno)
 
-    def displayServiceManagerItems(self, serviceitem, slideno):
+    def displayServiceManagerItems(self, serviceItem, slideno):
         """
         Loads a ServiceItem into the system from ServiceManager
         Display the slide number passed
         """
         log.debug(u'displayServiceManagerItems Start')
+        self.slideList = {}
         width = self.parent.ControlSplitter.sizes()[self.split]
         #Set pointing cursor when we have somthing to point at
         self.PreviewListWidget.setCursor(QtCore.Qt.PointingHandCursor)
         before = time.time()
-        self.serviceItem = serviceitem
+        self.serviceItem = serviceItem
         self.PreviewListWidget.clear()
         self.PreviewListWidget.setRowCount(0)
         self.PreviewListWidget.setColumnWidth(0, width)
@@ -446,8 +447,11 @@
                 self.PreviewListWidget.rowCount() + 1)
             item = QtGui.QTableWidgetItem()
             slide_height = 0
-            #It is a Image
-            if not self.serviceItem.is_text():
+            #It is a based Text Render
+            if self.serviceItem.is_text():
+                self.slideList[frame[u'verseTag']] = framenumber
+                item.setText(frame[u'text'])
+            else:
                 label = QtGui.QLabel()
                 label.setMargin(4)
                 pixmap = self.parent.RenderManager.resize_image(frame[u'image'])
@@ -455,8 +459,6 @@
                 label.setPixmap(QtGui.QPixmap.fromImage(pixmap))
                 self.PreviewListWidget.setCellWidget(framenumber, 0, label)
                 slide_height = width * self.parent.RenderManager.screen_ratio
-            else:
-                item.setText(frame[u'text'])
             self.PreviewListWidget.setItem(framenumber, 0, item)
             if slide_height != 0:
                 self.PreviewListWidget.setRowHeight(framenumber, slide_height)
@@ -468,12 +470,14 @@
             self.PreviewListWidget.selectRow(self.PreviewListWidget.rowCount())
         else:
             self.PreviewListWidget.selectRow(slideno)
+        self.enableToolBar(serviceItem)
         self.onSlideSelected()
         self.PreviewListWidget.setFocus()
         log.log(15, u'Display Rendering took %4s' % (time.time() - before))
         if self.isLive:
             self.serviceItem.request_audit()
         log.debug(u'displayServiceManagerItems End')
+        print self.slideList
 
     #Screen event methods
     def onSlideSelectedFirst(self):
@@ -517,10 +521,10 @@
             else:
                 before = time.time()
                 frame = self.serviceItem.get_rendered_frame(row)
-                self.SlidePreview.setPixmap(QtGui.QPixmap.fromImage(frame))
+                self.SlidePreview.setPixmap(QtGui.QPixmap.fromImage(frame[u'main']))
                 log.log(15, u'Slide Rendering took %4s' % (time.time() - before))
                 if self.isLive:
-                    self.parent.mainDisplay.frameView(frame)
+                    self.parent.mainDisplay.frameView(frame, True)
             self.selectedRow = row
 
     def onSlideChange(self, row):

=== modified file 'openlp/plugins/bibles/lib/mediaitem.py'
--- openlp/plugins/bibles/lib/mediaitem.py	2009-11-13 21:24:59 +0000
+++ openlp/plugins/bibles/lib/mediaitem.py	2009-11-29 18:25:21 +0000
@@ -276,8 +276,8 @@
 
     def initialise(self):
         log.debug(u'bible manager initialise')
-        self.loadBibles()
         self.parent.biblemanager.media = self
+        self.loadBibles()
         self.configUpdated()
         log.debug(u'bible manager initialise complete')
 

=== modified file 'openlp/plugins/songs/forms/editsongform.py'
--- openlp/plugins/songs/forms/editsongform.py	2009-11-13 21:24:59 +0000
+++ openlp/plugins/songs/forms/editsongform.py	2009-11-29 18:25:21 +0000
@@ -23,6 +23,7 @@
 ###############################################################################
 
 import logging
+import re
 
 from PyQt4 import QtCore, QtGui
 
@@ -110,6 +111,7 @@
         self.AuthorsListView.setAlternatingRowColors(True)
         self.TopicsListView.setSortingEnabled(False)
         self.TopicsListView.setAlternatingRowColors(True)
+        self.findVerseSplit = re.compile(u'---\[\]---\n', re.UNICODE)
 
     def initialise(self):
         self.VerseEditButton.setEnabled(False)
@@ -216,11 +218,17 @@
             songXML = SongXMLParser(self.song.lyrics)
             verseList = songXML.get_verses()
             for verse in verseList:
-                self.VerseListWidget.addItem(verse[1])
+                variant = u'%s:%s' % (verse[0][u'type'], verse[0][u'label'])
+                item = QtGui.QListWidgetItem(verse[1])
+                item.setData(QtCore.Qt.UserRole, QtCore.QVariant(variant))
+                self.VerseListWidget.addItem(item)
         else:
             verses = self.song.lyrics.split(u'\n\n')
-            for verse in verses:
-                self.VerseListWidget.addItem(verse)
+            for count, verse in enumerate(verses):
+                item = QtGui.QListWidgetItem(verse)
+                variant = u'Verse:%s' % count + 1
+                item.setData(QtCore.Qt.UserRole, QtCore.QVariant(variant))
+                self.VerseListWidget.addItem(item)
         # clear the results
         self.AuthorsListView.clear()
         for author in self.song.authors:
@@ -308,15 +316,23 @@
     def onVerseAddButtonClicked(self):
         self.verse_form.setVerse(u'')
         self.verse_form.exec_()
-        self.VerseListWidget.addItem(self.verse_form.getVerse())
+        afterText, verse, subVerse = self.verse_form.getVerse()
+        data = u'%s:%s' %(verse, subVerse)
+        item = QtGui.QListWidgetItem(afterText)
+        item.setData(QtCore.Qt.UserRole, QtCore.QVariant(data))
+        item.setText(afterText)
+        self.VerseListWidget.addItem(item)
 
     def onVerseEditButtonClicked(self):
         item = self.VerseListWidget.currentItem()
         if item:
             tempText = item.text()
-            self.verse_form.setVerse(tempText)
+            verseId = unicode((item.data(QtCore.Qt.UserRole)).toString())
+            self.verse_form.setVerse(tempText, True, verseId)
             self.verse_form.exec_()
-            afterText = self.verse_form.getVerse()
+            afterText, verse, subVerse = self.verse_form.getVerse()
+            data = u'%s:%s' %(verse, subVerse)
+            item.setData(QtCore.Qt.UserRole, QtCore.QVariant(data))
             item.setText(afterText)
             #number of lines has change
             if len(tempText.split(u'\n')) != len(afterText.split(u'\n')):
@@ -335,17 +351,29 @@
         if self.VerseListWidget.count() > 0:
             for row in range(0, self.VerseListWidget.count()):
                 item = self.VerseListWidget.item(row)
+                field = unicode((item.data(QtCore.Qt.UserRole)).toString())
+                verse_list += u'---[%s]---\n' % field
                 verse_list += item.text()
-                verse_list += u'\n---\n'
+                verse_list += u'\n'
             self.verse_form.setVerse(verse_list)
         else:
             self.verse_form.setVerse(u'')
         if self.verse_form.exec_():
-            verse_list = self.verse_form.getVerse()
-            verse_list = verse_list.replace(u'\r\n', u'\n')
+            verse_list = self.verse_form.getVerseAll()
+            verse_list = unicode(verse_list.replace(u'\r\n', u'\n'))
             self.VerseListWidget.clear()
-            for row in verse_list.split(u'\n---\n'):
-                self.VerseListWidget.addItem(row)
+            for row in self.findVerseSplit.split(verse_list):
+                for match in row.split(u'---['):
+                    for count, parts in enumerate(match.split(u']---\n')):
+                        if len(parts) > 1:
+                            if count == 0:
+                                variant = parts
+                            else:
+                                if parts.endswith(u'\n'):
+                                    parts = parts.rstrip(u'\n')
+                                item = QtGui.QListWidgetItem(parts)
+                                item.setData(QtCore.Qt.UserRole, QtCore.QVariant(variant))
+                                self.VerseListWidget.addItem(item)
         self.VerseListWidget.repaint()
 
     def onVerseDeleteButtonClicked(self):
@@ -372,6 +400,14 @@
             self.SongTabWidget.setCurrentIndex(2)
             self.AuthorsListView.setFocus()
             return False, self.trUtf8(u'You need to provide at least one author.')
+        for verse in unicode(self.VerseOrderEdit.text()):
+            if verse.isdigit() or u' BC'.find(verse) > -1:
+                pass
+            else:
+                self.SongTabWidget.setCurrentIndex(0)
+                self.VerseOrderEdit.setFocus()
+                return False, \
+                    self.trUtf8('Invalid verse entry - values must be Numeric, B or C')
         return True, u''
 
     def onTitleEditItemLostFocus(self):
@@ -443,15 +479,13 @@
             sxml.add_lyrics_to_song()
             count = 1
             text = u' '
-            verse_order = u''
             for i in range (0, self.VerseListWidget.count()):
-                sxml.add_verse_to_lyrics(u'Verse', unicode(count),
-                    unicode(self.VerseListWidget.item(i).text()))
+                item = self.VerseListWidget.item(i)
+                verseId = unicode((item.data(QtCore.Qt.UserRole)).toString())
+                bits = verseId.split(u':')
+                sxml.add_verse_to_lyrics(bits[0], bits[1], unicode(item.text()))
                 text = text + unicode(self.VerseListWidget.item(i).text()) + u' '
-                verse_order = verse_order + unicode(count) + u' '
                 count += 1
-            if self.song.verse_order is None:
-                self.song.verse_order = verse_order
             text = text.replace(u'\'', u'')
             text = text.replace(u',', u'')
             text = text.replace(u';', u'')

=== modified file 'openlp/plugins/songs/forms/editversedialog.py'
--- openlp/plugins/songs/forms/editversedialog.py	2009-10-24 16:40:36 +0000
+++ openlp/plugins/songs/forms/editversedialog.py	2009-11-29 18:25:21 +0000
@@ -1,52 +1,95 @@
 # -*- coding: utf-8 -*-
-# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
 
-###############################################################################
-# OpenLP - Open Source Lyrics Projection                                      #
-# --------------------------------------------------------------------------- #
-# Copyright (c) 2008-2009 Raoul Snyman                                        #
-# Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley, Carsten      #
-# Tinggaard, Jon Tibble, Jonathan Corwin, Maikel Stuivenberg, Scott Guerrieri #
-# --------------------------------------------------------------------------- #
-# 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                          #
-###############################################################################
+# Form implementation generated from reading ui file 'editversedialog.ui'
+#
+# Created: Fri Nov 27 18:35:12 2009
+#      by: PyQt4 UI code generator 4.6.2
+#
+# WARNING! All changes made in this file will be lost!
 
 from PyQt4 import QtCore, QtGui
 
 class Ui_EditVerseDialog(object):
     def setupUi(self, EditVerseDialog):
-        EditVerseDialog.setObjectName(u'EditVerseDialog')
-        EditVerseDialog.resize(492, 373)
+        EditVerseDialog.setObjectName("EditVerseDialog")
+        EditVerseDialog.resize(492, 494)
         EditVerseDialog.setModal(True)
-        self.DialogLayout = QtGui.QVBoxLayout(EditVerseDialog)
-        self.DialogLayout.setSpacing(8)
-        self.DialogLayout.setMargin(8)
-        self.DialogLayout.setObjectName(u'DialogLayout')
-        self.VerseTextEdit = QtGui.QTextEdit(EditVerseDialog)
+        self.widget = QtGui.QWidget(EditVerseDialog)
+        self.widget.setGeometry(QtCore.QRect(9, 12, 471, 471))
+        self.widget.setObjectName("widget")
+        self.verticalLayout = QtGui.QVBoxLayout(self.widget)
+        self.verticalLayout.setObjectName("verticalLayout")
+        self.horizontalLayout = QtGui.QHBoxLayout()
+        self.horizontalLayout.setObjectName("horizontalLayout")
+        self.VerseListComboBox = QtGui.QComboBox(self.widget)
+        self.VerseListComboBox.setObjectName("VerseListComboBox")
+        self.VerseListComboBox.addItem("")
+        self.VerseListComboBox.setItemText(0, "")
+        self.VerseListComboBox.addItem("")
+        self.VerseListComboBox.addItem("")
+        self.VerseListComboBox.addItem("")
+        self.horizontalLayout.addWidget(self.VerseListComboBox)
+        self.SubVerseListComboBox = QtGui.QComboBox(self.widget)
+        self.SubVerseListComboBox.setObjectName("SubVerseListComboBox")
+        self.SubVerseListComboBox.addItem("")
+        self.SubVerseListComboBox.setItemText(0, "")
+        self.SubVerseListComboBox.addItem("")
+        self.SubVerseListComboBox.addItem("")
+        self.SubVerseListComboBox.addItem("")
+        self.SubVerseListComboBox.addItem("")
+        self.SubVerseListComboBox.addItem("")
+        self.SubVerseListComboBox.addItem("")
+        self.SubVerseListComboBox.addItem("")
+        self.SubVerseListComboBox.addItem("")
+        self.SubVerseListComboBox.addItem("")
+        self.SubVerseListComboBox.addItem("")
+        self.SubVerseListComboBox.addItem("")
+        self.horizontalLayout.addWidget(self.SubVerseListComboBox)
+        self.verticalLayout.addLayout(self.horizontalLayout)
+        self.VerseTextEdit = QtGui.QTextEdit(self.widget)
         self.VerseTextEdit.setAcceptRichText(False)
-        self.VerseTextEdit.setObjectName(u'VerseTextEdit')
-        self.DialogLayout.addWidget(self.VerseTextEdit)
-        self.ButtonBox = QtGui.QDialogButtonBox(EditVerseDialog)
+        self.VerseTextEdit.setObjectName("VerseTextEdit")
+        self.verticalLayout.addWidget(self.VerseTextEdit)
+        self.horizontalLayout_2 = QtGui.QHBoxLayout()
+        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+        self.addVerse = QtGui.QPushButton(self.widget)
+        self.addVerse.setObjectName("addVerse")
+        self.horizontalLayout_2.addWidget(self.addVerse)
+        self.addChorus = QtGui.QPushButton(self.widget)
+        self.addChorus.setObjectName("addChorus")
+        self.horizontalLayout_2.addWidget(self.addChorus)
+        self.addBridge = QtGui.QPushButton(self.widget)
+        self.addBridge.setObjectName("addBridge")
+        self.horizontalLayout_2.addWidget(self.addBridge)
+        self.verticalLayout.addLayout(self.horizontalLayout_2)
+        self.ButtonBox = QtGui.QDialogButtonBox(self.widget)
         self.ButtonBox.setOrientation(QtCore.Qt.Horizontal)
         self.ButtonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Save)
-        self.ButtonBox.setObjectName(u'ButtonBox')
-        self.DialogLayout.addWidget(self.ButtonBox)
+        self.ButtonBox.setObjectName("ButtonBox")
+        self.verticalLayout.addWidget(self.ButtonBox)
+
         self.retranslateUi(EditVerseDialog)
-        QtCore.QObject.connect(self.ButtonBox, QtCore.SIGNAL(u'accepted()'), EditVerseDialog.accept)
-        QtCore.QObject.connect(self.ButtonBox, QtCore.SIGNAL(u'rejected()'), EditVerseDialog.reject)
+        QtCore.QObject.connect(self.ButtonBox, QtCore.SIGNAL("accepted()"), EditVerseDialog.accept)
+        QtCore.QObject.connect(self.ButtonBox, QtCore.SIGNAL("rejected()"), EditVerseDialog.reject)
         QtCore.QMetaObject.connectSlotsByName(EditVerseDialog)
-        self.VerseTextEdit.setFocus(QtCore.Qt.OtherFocusReason)
 
     def retranslateUi(self, EditVerseDialog):
-        EditVerseDialog.setWindowTitle(self.trUtf8(u'Edit Verse'))
+        EditVerseDialog.setWindowTitle(QtGui.QApplication.translate("EditVerseDialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
+        self.VerseListComboBox.setItemText(1, QtGui.QApplication.translate("EditVerseDialog", "Verse", None, QtGui.QApplication.UnicodeUTF8))
+        self.VerseListComboBox.setItemText(2, QtGui.QApplication.translate("EditVerseDialog", "Chorus", None, QtGui.QApplication.UnicodeUTF8))
+        self.VerseListComboBox.setItemText(3, QtGui.QApplication.translate("EditVerseDialog", "Bridge", None, QtGui.QApplication.UnicodeUTF8))
+        self.SubVerseListComboBox.setItemText(1, QtGui.QApplication.translate("EditVerseDialog", "1", None, QtGui.QApplication.UnicodeUTF8))
+        self.SubVerseListComboBox.setItemText(2, QtGui.QApplication.translate("EditVerseDialog", "1a", None, QtGui.QApplication.UnicodeUTF8))
+        self.SubVerseListComboBox.setItemText(3, QtGui.QApplication.translate("EditVerseDialog", "1b", None, QtGui.QApplication.UnicodeUTF8))
+        self.SubVerseListComboBox.setItemText(4, QtGui.QApplication.translate("EditVerseDialog", "2", None, QtGui.QApplication.UnicodeUTF8))
+        self.SubVerseListComboBox.setItemText(5, QtGui.QApplication.translate("EditVerseDialog", "2a", None, QtGui.QApplication.UnicodeUTF8))
+        self.SubVerseListComboBox.setItemText(6, QtGui.QApplication.translate("EditVerseDialog", "2b", None, QtGui.QApplication.UnicodeUTF8))
+        self.SubVerseListComboBox.setItemText(7, QtGui.QApplication.translate("EditVerseDialog", "3", None, QtGui.QApplication.UnicodeUTF8))
+        self.SubVerseListComboBox.setItemText(8, QtGui.QApplication.translate("EditVerseDialog", "4", None, QtGui.QApplication.UnicodeUTF8))
+        self.SubVerseListComboBox.setItemText(9, QtGui.QApplication.translate("EditVerseDialog", "5", None, QtGui.QApplication.UnicodeUTF8))
+        self.SubVerseListComboBox.setItemText(10, QtGui.QApplication.translate("EditVerseDialog", "6", None, QtGui.QApplication.UnicodeUTF8))
+        self.SubVerseListComboBox.setItemText(11, QtGui.QApplication.translate("EditVerseDialog", "7", None, QtGui.QApplication.UnicodeUTF8))
+        self.addVerse.setText(QtGui.QApplication.translate("EditVerseDialog", "Verse", None, QtGui.QApplication.UnicodeUTF8))
+        self.addChorus.setText(QtGui.QApplication.translate("EditVerseDialog", "Chorus", None, QtGui.QApplication.UnicodeUTF8))
+        self.addBridge.setText(QtGui.QApplication.translate("EditVerseDialog", "Bridge", None, QtGui.QApplication.UnicodeUTF8))
+

=== modified file 'openlp/plugins/songs/forms/editverseform.py'
--- openlp/plugins/songs/forms/editverseform.py	2009-09-25 00:43:42 +0000
+++ openlp/plugins/songs/forms/editverseform.py	2009-11-29 18:25:21 +0000
@@ -23,24 +23,65 @@
 ###############################################################################
 
 from PyQt4 import QtCore, QtGui
-
 from editversedialog import Ui_EditVerseDialog
 
 class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
     """
     This is the form that is used to edit the verses of the song.
     """
-
     def __init__(self, parent=None):
         """
         Constructor
         """
         QtGui.QDialog.__init__(self, parent)
         self.setupUi(self)
-
-    def setVerse(self, verse):
-        self.VerseTextEdit.setPlainText(verse)
+        QtCore.QObject.connect(self.addVerse,
+            QtCore.SIGNAL(u'clicked()'), self.onAddVerse)
+        QtCore.QObject.connect(self.addChorus,
+            QtCore.SIGNAL(u'clicked()'), self.onAddChorus)
+        QtCore.QObject.connect(self.addBridge,
+            QtCore.SIGNAL(u'clicked()'), self.onAddBridge)
+
+    def onAddBridge(self):
+        self.VerseTextEdit.insertPlainText(u'---[Bridge:1]---\n')
+
+    def onAddChorus(self):
+        self.VerseTextEdit.insertPlainText(u'---[Chorus:1]---\n')
+
+    def onAddVerse(self):
+        self.VerseTextEdit.insertPlainText(u'---[Verse:1]---\n')
+
+    def setVerse(self, text, single=False, tag=0):
+        posVerse = 0
+        posSub = 0
+        if single:
+            id = tag.split(u':')
+            posVerse = self.VerseListComboBox.findText(id[0], QtCore.Qt.MatchExactly)
+            posSub = self.SubVerseListComboBox.findText(id[1], QtCore.Qt.MatchExactly)
+            if posVerse == -1:
+                posVerse = 0
+            if posSub == -1:
+                posSub = 0
+            self.VerseListComboBox.setEnabled(True)
+            self.SubVerseListComboBox.setEnabled(True)
+            self.addBridge.setEnabled(False)
+            self.addChorus.setEnabled(False)
+            self.addVerse.setEnabled(False)
+        else:
+            self.VerseListComboBox.setEnabled(False)
+            self.SubVerseListComboBox.setEnabled(False)
+            self.addBridge.setEnabled(True)
+            self.addChorus.setEnabled(True)
+            self.addVerse.setEnabled(True)
+        self.VerseListComboBox.setCurrentIndex(posVerse)
+        self.SubVerseListComboBox.setCurrentIndex(posSub)
+        self.VerseTextEdit.setPlainText(text)
         self.VerseTextEdit.setFocus(QtCore.Qt.OtherFocusReason)
 
     def getVerse(self):
-        return self.VerseTextEdit.toPlainText()
+       return self.VerseTextEdit.toPlainText(), \
+            unicode(self.VerseListComboBox.currentText()), \
+            unicode(self.SubVerseListComboBox.currentText())
+
+    def getVerseAll(self):
+       return self.VerseTextEdit.toPlainText()

=== modified file 'openlp/plugins/songs/lib/mediaitem.py'
--- openlp/plugins/songs/lib/mediaitem.py	2009-11-14 09:41:11 +0000
+++ openlp/plugins/songs/lib/mediaitem.py	2009-11-29 18:25:21 +0000
@@ -295,7 +295,8 @@
             verseList = songXML.get_verses()
             for verse in verseList:
                 if verse[1]:
-                    service_item.add_from_text(verse[1][:30], verse[1])
+                    verseTag = u'%s:%s' % (verse[0][u'type'], verse[0][u'label'])
+                    service_item.add_from_text(verse[1][:30], verse[1], verseTag)
         else:
             verses = song.lyrics.split(u'\n\n')
             for slide in verses:

=== modified file 'resources/forms/editversedialog.ui'
--- resources/forms/editversedialog.ui	2009-03-07 21:38:59 +0000
+++ resources/forms/editversedialog.ui	2009-11-29 18:25:21 +0000
@@ -1,45 +1,167 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
  <class>EditVerseDialog</class>
- <widget class="QDialog" name="EditVerseDialog" >
-  <property name="geometry" >
+ <widget class="QDialog" name="EditVerseDialog">
+  <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>492</width>
-    <height>373</height>
+    <height>494</height>
    </rect>
   </property>
-  <property name="windowTitle" >
+  <property name="windowTitle">
    <string>Dialog</string>
   </property>
-  <property name="modal" >
+  <property name="modal">
    <bool>true</bool>
   </property>
-  <layout class="QVBoxLayout" name="DialogLayout" >
-   <property name="spacing" >
-    <number>8</number>
-   </property>
-   <property name="margin" >
-    <number>8</number>
-   </property>
-   <item>
-    <widget class="QTextEdit" name="VerseTextEdit" >
-     <property name="acceptRichText" >
-      <bool>false</bool>
-     </property>
-    </widget>
-   </item>
-   <item>
-    <widget class="QDialogButtonBox" name="ButtonBox" >
-     <property name="orientation" >
-      <enum>Qt::Horizontal</enum>
-     </property>
-     <property name="standardButtons" >
-      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
-     </property>
-    </widget>
-   </item>
-  </layout>
+  <widget class="QWidget" name="">
+   <property name="geometry">
+    <rect>
+     <x>9</x>
+     <y>12</y>
+     <width>471</width>
+     <height>471</height>
+    </rect>
+   </property>
+   <layout class="QVBoxLayout" name="verticalLayout">
+    <item>
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <item>
+       <widget class="QComboBox" name="VerseListComboBox">
+        <item>
+         <property name="text">
+          <string/>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Verse</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Chorus</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Bridge</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item>
+       <widget class="QComboBox" name="SubVerseListComboBox">
+        <item>
+         <property name="text">
+          <string/>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>1</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>1a</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>1b</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>2</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>2a</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>2b</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>3</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>4</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>5</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>6</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>7</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+     </layout>
+    </item>
+    <item>
+     <widget class="QTextEdit" name="VerseTextEdit">
+      <property name="acceptRichText">
+       <bool>false</bool>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <layout class="QHBoxLayout" name="horizontalLayout_2">
+      <item>
+       <widget class="QPushButton" name="addVerse">
+        <property name="text">
+         <string>Verse</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="addChorus">
+        <property name="text">
+         <string>Chorus</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="addBridge">
+        <property name="text">
+         <string>Bridge</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </item>
+    <item>
+     <widget class="QDialogButtonBox" name="ButtonBox">
+      <property name="orientation">
+       <enum>Qt::Horizontal</enum>
+      </property>
+      <property name="standardButtons">
+       <set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
+      </property>
+     </widget>
+    </item>
+   </layout>
+  </widget>
  </widget>
  <resources/>
  <connections>
@@ -49,11 +171,11 @@
    <receiver>EditVerseDialog</receiver>
    <slot>accept()</slot>
    <hints>
-    <hint type="sourcelabel" >
+    <hint type="sourcelabel">
      <x>248</x>
      <y>254</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>157</x>
      <y>274</y>
     </hint>
@@ -65,11 +187,11 @@
    <receiver>EditVerseDialog</receiver>
    <slot>reject()</slot>
    <hints>
-    <hint type="sourcelabel" >
+    <hint type="sourcelabel">
      <x>316</x>
      <y>260</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>286</x>
      <y>274</y>
     </hint>