← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~j-corwin/openlp/sof into lp:openlp

 

Jonathan Corwin has proposed merging lp:~j-corwin/openlp/sof into lp:openlp.

Requested reviews:
  OpenLP Core (openlp-core)


General purpose OpenOffice.org Writer/Impress (Word/Powerpoint) import.
Also error trap so those without OOo can still see songs
-- 
https://code.launchpad.net/~j-corwin/openlp/sof/+merge/23301
Your team OpenLP Core is subscribed to branch lp:openlp.
=== modified file 'openlp/plugins/songs/lib/__init__.py'
--- openlp/plugins/songs/lib/__init__.py	2010-04-02 14:10:10 +0000
+++ openlp/plugins/songs/lib/__init__.py	2010-04-13 07:39:21 +0000
@@ -27,4 +27,5 @@
 from songstab import SongsTab
 from mediaitem import SongMediaItem
 from sofimport import SofImport
+from oooimport import OooImport
 from songimport import SongImport

=== added file 'openlp/plugins/songs/lib/oooimport.py'
--- openlp/plugins/songs/lib/oooimport.py	1970-01-01 00:00:00 +0000
+++ openlp/plugins/songs/lib/oooimport.py	2010-04-13 07:39:21 +0000
@@ -0,0 +1,197 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection                                      #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2010 Raoul Snyman                                        #
+# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael      #
+# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin      #
+# Thompson, Jon Tibble, Carsten Tinggaard                                     #
+# --------------------------------------------------------------------------- #
+# This program is free software; you can redistribute it and/or modify it     #
+# under the terms of the GNU General Public License as published by the Free  #
+# Software Foundation; version 2 of the License.                              #
+#                                                                             #
+# This program is distributed in the hope that it will be useful, but WITHOUT #
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       #
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    #
+# more details.                                                               #
+#                                                                             #
+# You should have received a copy of the GNU General Public License along     #
+# with this program; if not, write to the Free Software Foundation, Inc., 59  #
+# Temple Place, Suite 330, Boston, MA 02111-1307 USA                          #
+###############################################################################
+
+import os
+from PyQt4 import QtCore
+from songimport import SongImport
+
+if os.name == u'nt':
+    from win32com.client import Dispatch
+    PAGE_BEFORE = 4
+    PAGE_AFTER = 5
+    PAGE_BOTH = 6
+else:
+    try:
+        import uno
+        from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH
+    except:
+        pass
+class OooImport(object):
+    """
+    Import songs from Impress/Powerpoint docs using Impress 
+    """
+    def __init__(self, songmanager):
+        """
+        Initialise the class. Requires a songmanager class which is passed
+        to SongImport for writing song to disk
+        """
+        self.song = None
+        self.manager = songmanager
+        self.document = None
+        self.process_started = False
+
+    def import_docs(self, filenames):
+        self.start_ooo()
+        for filename in filenames:
+            filename = unicode(filename)
+            if os.path.isfile(filename):
+                self.open_ooo_file(filename)
+                if self.document:
+                    if self.document.supportsService(
+                        "com.sun.star.presentation.PresentationDocument"):
+                        self.process_pres()
+                    if self.document.supportsService(
+                            "com.sun.star.text.TextDocument"):
+                        self.process_doc()
+                    self.close_ooo_file()
+        self.close_ooo()
+
+    def start_ooo(self):
+        """
+        Start OpenOffice.org process
+        TODO: The presentation/Impress plugin may already have it running
+        """
+        if os.name == u'nt':
+            self.start_ooo_process()
+            self.desktop = self.manager.createInstance(u'com.sun.star.frame.Desktop')
+        else:
+            context = uno.getComponentContext()
+            resolver = context.ServiceManager.createInstanceWithContext(
+                u'com.sun.star.bridge.UnoUrlResolver', context)
+            ctx = None
+            loop = 0
+            while ctx is None and loop < 5:
+                try:
+                    ctx = resolver.resolve(u'uno:socket,host=localhost,' \
+                        + 'port=2002;urp;StarOffice.ComponentContext')
+                except:
+                    pass
+                self.start_ooo_process()
+                loop += 1
+            manager = ctx.ServiceManager
+            self.desktop = manager.createInstanceWithContext(
+                "com.sun.star.frame.Desktop", ctx )
+            
+    def start_ooo_process(self):
+        try:
+            if os.name == u'nt':
+                self.manager = Dispatch(u'com.sun.star.ServiceManager')
+                self.manager._FlagAsMethod(u'Bridge_GetStruct')
+                self.manager._FlagAsMethod(u'Bridge_GetValueObject')
+            else:
+                cmd = u'openoffice.org -nologo -norestore -minimized -invisible ' \
+                    + u'-nofirststartwizard ' \
+                    + '-accept="socket,host=localhost,port=2002;urp;"'
+                process = QtCore.QProcess()
+                process.startDetached(cmd)
+                process.waitForStarted()
+            self.process_started = True
+        except:
+            pass
+
+    def open_ooo_file(self, filepath):
+        """
+        Open the passed file in OpenOffice.org Impress
+        """
+        if os.name == u'nt':
+            url = u'file:///' + filepath.replace(u'\\', u'/')
+            url = url.replace(u':', u'|').replace(u' ', u'%20')
+        else:
+            url = uno.systemPathToFileUrl(filepath)
+        properties = []
+        properties = tuple(properties)
+        try:
+            self.document = self.desktop.loadComponentFromURL(url, u'_blank',
+                0, properties)
+            if not self.document.supportsService(                   
+                "com.sun.star.presentation.PresentationDocument")   \
+                and not self.document.supportsService(              
+                "com.sun.star.text.TextDocument"):
+                self.close_ooo_file()
+        except:
+            pass
+        return   
+
+    def close_ooo_file(self):
+        """
+        Close file. 
+        """
+        self.document.close(True)
+        self.document = None
+
+    def close_ooo(self):
+        """
+        Close OOo. But only if we started it and not on windows
+        """
+        if self.process_started:
+            self.desktop.terminate()
+
+    def process_pres(self):
+        """
+        Process the file
+        """            
+        doc = self.document
+        slides = doc.getDrawPages()
+        text = u''
+        for slide_no in range(slides.getCount()):
+            slide = slides.getByIndex(slide_no)   
+            slidetext = u''
+            for idx in range(slide.getCount()):
+                shape = slide.getByIndex(idx)
+                if shape.supportsService("com.sun.star.drawing.Text"):
+                    if shape.getString().strip() != u'':
+                        slidetext += shape.getString().strip() + u'\n\n'
+            if slidetext.strip() == u'':
+                slidetext = u'\f'
+            text += slidetext
+        song = SongImport(self.manager)
+        songs = SongImport.process_songs_text(self.manager, text)
+        for song in songs:
+            song.finish()
+        return 
+
+    def process_doc(self):
+        """
+        Process the doc file, a paragraph at a time
+        """            
+        text = u''
+        paragraphs = self.document.getText().createEnumeration()
+        while paragraphs.hasMoreElements():
+            paratext = u''
+            paragraph = paragraphs.nextElement()
+            if paragraph.supportsService("com.sun.star.text.Paragraph"):
+                textportions = paragraph.createEnumeration()
+                while textportions.hasMoreElements():
+                    textportion = textportions.nextElement()
+                    if textportion.BreakType in (PAGE_BEFORE, PAGE_BOTH):
+                        paratext += u'\f'
+                    paratext += textportion.getString()
+                    if textportion.BreakType in (PAGE_AFTER, PAGE_BOTH):
+                        paratext += u'\f'
+            text += paratext + u'\n'
+        songs = SongImport.process_songs_text(self.manager, text)
+        for song in songs:
+            song.finish()
+

=== modified file 'openlp/plugins/songs/lib/sofimport.py'
--- openlp/plugins/songs/lib/sofimport.py	2010-04-11 17:52:51 +0000
+++ openlp/plugins/songs/lib/sofimport.py	2010-04-13 07:39:21 +0000
@@ -29,12 +29,12 @@
 # http://www.oooforum.org/forum/viewtopic.phtml?t=14409
 # http://wiki.services.openoffice.org/wiki/Python
 
+import re
 import os
-import re
-
+import time
 from PyQt4 import QtCore
-
 from songimport import SongImport
+from oooimport import OooImport
 
 if os.name == u'nt':
     from win32com.client import Dispatch
@@ -49,7 +49,7 @@
     from com.sun.star.awt.FontSlant import ITALIC
     from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH
 
-class SofImport(object):
+class SofImport(OooImport):
     """
     Import songs provided on disks with the Songs of Fellowship music books
     VOLS1_2.RTF, sof3words.rtf and sof4words.rtf
@@ -70,83 +70,16 @@
         Initialise the class. Requires a songmanager class which is passed
         to SongImport for writing song to disk
         """
-        self.song = None
-        self.manager = songmanager
-        self.process_started = False
+        OooImport.__init__(self,songmanager)
 
     def import_sof(self, filename):
         self.start_ooo()
         self.open_ooo_file(filename)
-        self.process_doc()
+        self.process_sof_file()
+        self.close_ooo_file()
         self.close_ooo()
 
-    def start_ooo(self):
-        """
-        Start OpenOffice.org process
-        TODO: The presentation/Impress plugin may already have it running
-        """
-        if os.name == u'nt':
-            self.start_ooo_process()
-            self.desktop = self.manager.createInstance(u'com.sun.star.frame.Desktop')
-        else:
-            context = uno.getComponentContext()
-            resolver = context.ServiceManager.createInstanceWithContext(
-                u'com.sun.star.bridge.UnoUrlResolver', context)
-            ctx = None
-            loop = 0
-            while ctx is None and loop < 5:
-                try:
-                    ctx = resolver.resolve(u'uno:socket,host=localhost,' \
-                        + 'port=2002;urp;StarOffice.ComponentContext')
-                except:
-                    pass
-                self.start_ooo_process()
-                loop += 1
-            manager = ctx.ServiceManager
-            self.desktop = manager.createInstanceWithContext(
-                "com.sun.star.frame.Desktop", ctx )
-            
-    def start_ooo_process(self):
-        try:
-            if os.name == u'nt':
-                self.manager = Dispatch(u'com.sun.star.ServiceManager')
-                self.manager._FlagAsMethod(u'Bridge_GetStruct')
-                self.manager._FlagAsMethod(u'Bridge_GetValueObject')
-            else:
-                cmd = u'openoffice.org -nologo -norestore -minimized -invisible ' \
-                    + u'-nofirststartwizard ' \
-                    + '-accept="socket,host=localhost,port=2002;urp;"'
-                process = QtCore.QProcess()
-                process.startDetached(cmd)
-                process.waitForStarted()
-            self.process_started = True
-        except:
-            pass
-
-    def open_ooo_file(self, filepath):
-        """
-        Open the passed file in OpenOffice.org Writer
-        """
-        if os.name == u'nt':
-            url = u'file:///' + filepath.replace(u'\\', u'/')
-            url = url.replace(u':', u'|').replace(u' ', u'%20')
-        else:
-            url = uno.systemPathToFileUrl(filepath)
-        properties = []
-        properties = tuple(properties)
-        self.document = self.desktop.loadComponentFromURL(url, u'_blank',
-            0, properties)
-
-    def close_ooo(self):
-        """
-        Close RTF file. Note, on Windows we'll leave OOo running
-        Leave running on Windows
-        """
-        self.document.close(True)
-        if self.process_started:
-            self.desktop.terminate()
-
-    def process_doc(self):
+    def process_sof_file(self):
         """
         Process the RTF file, a paragraph at a time
         """            
@@ -247,7 +180,7 @@
         into line
         """
         text = textportion.getString()
-        text = self.tidy_text(text)
+        text = SongImport.tidy_text(text)
         if text.strip() == u'':
             return text
         if textportion.CharWeight == BOLD:
@@ -320,17 +253,7 @@
         "Mr Smith" and "Mrs Smith".
         """
         text = text.replace(u' and ', u' & ')
-        for author in text.split(u','):
-            authors = author.split(u'&')
-            for i in range(len(authors)):
-                author2 = authors[i].strip()
-                if author2.find(u' ') == -1 and i < len(authors) - 1:
-                    author2 = author2 + u' ' \
-                        + authors[i + 1].strip().split(u' ')[-1]
-                if author2.endswith(u'.'):
-                    author2 = author2[:-1]
-                if author2:
-                    self.song.add_author(author2)
+        self.song.parse_author(text)
 
     def add_verse_line(self, text):
         """
@@ -380,21 +303,6 @@
         self.currentverse = u''
         self.is_chorus = False
 
-    def tidy_text(self, text):
-        """
-        Get rid of some dodgy unicode and formatting characters we're not
-        interested in. Some can be converted to ascii.
-        """
-        text = text.replace(u'\t', u' ')
-        text = text.replace(u'\r', u'\n')
-        text = text.replace(u'\u2018', u'\'')
-        text = text.replace(u'\u2019', u'\'')
-        text = text.replace(u'\u201c', u'"')
-        text = text.replace(u'\u201d', u'"')
-        text = text.replace(u'\u2026', u'...')
-        text = text.replace(u'\u2013', u'-')
-        text = text.replace(u'\u2014', u'-')
-        return text
 
     def uncap_text(self, text):
         """ 

=== modified file 'openlp/plugins/songs/lib/songimport.py'
--- openlp/plugins/songs/lib/songimport.py	2010-04-03 19:17:37 +0000
+++ openlp/plugins/songs/lib/songimport.py	2010-04-13 07:39:21 +0000
@@ -24,9 +24,10 @@
 ###############################################################################
 
 import string
-from openlp.core.lib import SongXMLBuilder
+from PyQt4 import QtGui, QtCore
+from openlp.core.lib import SongXMLBuilder
 from openlp.plugins.songs.lib.models import Song, Author, Topic, Book
-        
+        
 class SongImport(object):
     """
     Helper class for import a song from a third party source into OpenLP
@@ -42,232 +43,328 @@
         
         song_manager is an instance of a SongManager, through which all
         database access is performed
-        """
+        """
         self.manager = song_manager
-        self.title = u''
+        self.title = u''
         self.song_number = u''
         self.alternate_title = u''
-        self.copyright = u''
-        self.comment = u''
-        self.theme_name = u''
-        self.ccli_number = u''    
-        self.authors = []           
-        self.topics = []            
-        self.song_book_name = u''   
-        self.song_book_pub = u''   
-        self.verse_order_list = []  
-        self.verses = []            
-        self.versecount = 0
-        self.choruscount = 0
-       
+        self.copyright = u''
+        self.comment = u''
+        self.theme_name = u''
+        self.ccli_number = u''    
+        self.authors = []           
+        self.topics = []            
+        self.song_book_name = u''   
+        self.song_book_pub = u''   
+        self.verse_order_list = []  
+        self.verses = []            
+        self.versecount = 0
+        self.choruscount = 0
+        self.copyright_string = unicode(QtGui.QApplication.translate( \
+            u'SongImport', u'copyright'))
+        self.copyright_symbol = unicode(QtGui.QApplication.translate( \
+            u'SongImport', u'©'))
+
+    @staticmethod
+    def process_songs_text(manager, text):
+        songs = []
+        songtexts = SongImport.tidy_text(text).split(u'\f')
+        song = SongImport(manager)
+        for songtext in songtexts:
+            if songtext.strip():
+                song.process_song_text(songtext.strip())
+                if song.check_complete():
+                    songs.append(song)
+                    song = SongImport(manager)
+        if song.check_complete():
+            songs.append(song)
+        return songs
+
+    @staticmethod
+    def tidy_text(text):
+        """
+        Get rid of some dodgy unicode and formatting characters we're not
+        interested in. Some can be converted to ascii.
+        """
+        text = text.replace(u'\t', u' ')
+        text = text.replace(u'\r\n', u'\n')
+        text = text.replace(u'\r', u'\n')
+        text = text.replace(u'\u2018', u'\'')
+        text = text.replace(u'\u2019', u'\'')
+        text = text.replace(u'\u201c', u'"')
+        text = text.replace(u'\u201d', u'"')
+        text = text.replace(u'\u2026', u'...')
+        text = text.replace(u'\u2013', u'-')
+        text = text.replace(u'\u2014', u'-')
+        # Remove surplus blank lines, spaces, trailing/leading spaces
+        while text.find(u'  ') >= 0:
+            text = text.replace(u'  ', u' ')
+        text = text.replace(u'\n ', u'\n')
+        text = text.replace(u' \n', u'\n')
+        text = text.replace(u'\n\n\n\n\n', u'\f')
+        text = text.replace(u'\f ', u'\f')
+        text = text.replace(u' \f', u'\f')
+        while text.find(u'\f\f') >= 0:
+            text = text.replace(u'\f\f', u'\f')
+        return text
+
+    def process_song_text(self, text):
+        versetexts = text.split(u'\n\n')
+        for versetext in versetexts:
+            if versetext.strip() != u'':
+                self.process_verse_text(versetext.strip())
+
+    def process_verse_text(self, text):
+        lines = text.split(u'\n')
+        if text.lower().find(self.copyright_string) >= 0 \
+            or text.lower().find(self.copyright_symbol) >= 0:
+            copyright_found = False
+            for line in lines:
+                if copyright_found or line.lower().find(self.copyright_string) >= 0\
+                    or line.lower().find(self.copyright_symbol) >= 0:
+                    copyright_found = True
+                    self.add_copyright(line)
+                else:
+                    self.parse_author(line)   
+            return                                             
+        if len(lines) == 1:
+            self.parse_author(lines[0])
+            return
+        if not self.get_title():
+            self.set_title(lines[0])
+        self.add_verse(text)
+       
     def get_title(self):
         """
         Return the title
-        """
-        return self.title
-        
+        """
+        return self.title
+        
     def get_copyright(self):
         """
         Return the copyright
-        """
-        return self.copyright
-        
+        """
+        return self.copyright
+        
     def get_song_number(self):
         """ 
         Return the song number 
-        """
-        return self.song_number
-        
+        """
+        return self.song_number
+        
     def set_title(self, title):
         """
         Set the title
-        """
-        self.title = title
+        """
+        self.title = title
  
     def set_alternate_title(self, title):
         """
         Set the alternate title
-        """
-        self.alternate_title = title
-
+        """
+        self.alternate_title = title
+
     def set_song_number(self, song_number):
         """ 
         Set the song number
-        """
-        self.song_number = song_number
-        
+        """
+        self.song_number = song_number
+        
     def set_song_book(self, song_book, publisher):
         """
         Set the song book name and publisher
-        """
-        self.song_book_name = song_book
-        self.song_book_pub = publisher
-
+        """
+        self.song_book_name = song_book
+        self.song_book_pub = publisher
+
     def add_copyright(self, copyright):
         """ 
         Build the copyright field
-        """
-        if self.copyright != u'':
-            self.copyright += ' '
-        self.copyright += copyright
-
-    def add_author(self, text):
+        """
+        if self.copyright.find(copyright) >= 0:
+            return
+        if self.copyright != u'':
+            self.copyright += ' '
+        self.copyright += copyright
+
+    def parse_author(self, text):
+        """
+        Add the author. OpenLP stores them individually so split by 'and', '&'
+        and comma.
+        However need to check for "Mr and Mrs Smith" and turn it to 
+        "Mr Smith" and "Mrs Smith".
+        """
+        for author in text.split(u','):
+            authors = author.split(u'&')
+            for i in range(len(authors)):
+                author2 = authors[i].strip()
+                if author2.find(u' ') == -1 and i < len(authors) - 1:
+                    author2 = author2 + u' ' \
+                        + authors[i + 1].strip().split(u' ')[-1]
+                if author2.endswith(u'.'):
+                    author2 = author2[:-1]
+                if author2:
+                    self.add_author(author2)
+
+    def add_author(self, author):
         """ 
         Add an author to the list
-        """
-        self.authors.append(text)
-        
-    def add_verse(self, verse, versetag):
+        """
+        if author in self.authors:
+            return
+        self.authors.append(author)
+        
+    def add_verse(self, verse, versetag=None):
         """
         Add a verse. This is the whole verse, lines split by \n
         Verse tag can be V1/C1/B etc, or 'V' and 'C' (will count the verses/
         choruses itself) or None, where it will assume verse
         It will also attempt to detect duplicates. In this case it will just
         add to the verse order
-        """        
-        for (oldversetag, oldverse) in self.verses:
-            if oldverse.strip() == verse.strip():
-                self.verse_order_list.append(oldversetag)
+        """        
+        for (oldversetag, oldverse) in self.verses:
+            if oldverse.strip() == verse.strip():
+                self.verse_order_list.append(oldversetag)
                 return
-        if versetag.startswith(u'C'):
-            self.choruscount += 1
-        if versetag == u'C':
-            versetag += unicode(self.choruscount)
-        if versetag == u'V' or not versetag:
-            self.versecount += 1
-            versetag = u'V' + unicode(self.versecount)
-        self.verses.append([versetag, verse.rstrip()])
-        self.verse_order_list.append(versetag)
-        if versetag.startswith(u'V') and self.contains_verse(u'C1'):
-            self.verse_order_list.append(u'C1')
-
+        if versetag == u'V' or not versetag:
+            self.versecount += 1
+            versetag = u'V' + unicode(self.versecount)
+        if versetag.startswith(u'C'):
+            self.choruscount += 1
+        if versetag == u'C':
+            versetag += unicode(self.choruscount)
+        self.verses.append([versetag, verse.rstrip()])
+        self.verse_order_list.append(versetag)
+        if versetag.startswith(u'V') and self.contains_verse(u'C1'):
+            self.verse_order_list.append(u'C1')
+
     def repeat_verse(self):
         """
         Repeat the previous verse in the verse order
-        """
-        self.verse_order_list.append(self.verse_order_list[-1])
+        """
+        self.verse_order_list.append(self.verse_order_list[-1])
 
     def contains_verse(self, versetag):
         return versetag in self.verse_order_list
-
+
     def check_complete(self):
         """
         Check the mandatory fields are entered (i.e. title and a verse)
         Author not checked here, if no author then "Author unknown" is 
         automatically added
-        """
-        if self.title == u'' or len(self.verses) == 0:
-            return False
-        else:
-            return True
-            
+        """
+        if self.title == u'' or len(self.verses) == 0:
+            return False
+        else:
+            return True
+            
     def remove_punctuation(self, text):	
         """
         Remove punctuation from the string for searchable fields
         """
-        for c in string.punctuation:
+        for c in string.punctuation:
             text = text.replace(c, u'')
-        return text
-            
+        return text
+            
     def finish(self):
         """
         All fields have been set to this song. Write it away
-        """
-        if len(self.authors) == 0:
-            self.authors.append(u'Author unknown')
-        self.commit_song()
+        """
+        if len(self.authors) == 0:
+            self.authors.append(u'Author unknown')
+        self.commit_song()
         #self.print_song()
-        
+        
     def commit_song(self):
         """
         Write the song and it's fields to disk
-        """
-        song = Song()
-        song.title = self.title
+        """
+        song = Song()
+        song.title = self.title
         song.search_title = self.remove_punctuation(self.title) \
-            + '@' + self.alternate_title
-        song.song_number = self.song_number
-        song.search_lyrics = u''
-        sxml = SongXMLBuilder()
-        sxml.new_document()
-        sxml.add_lyrics_to_song()
-        for (versetag, versetext) in self.verses:
-            if versetag[0] == u'C':
-                versetype = u'Chorus'
-            elif versetag[0] == u'V':
-                versetype = u'Verse'
-            elif versetag[0] == u'B':
-                versetype = u'Bridge'
-            elif versetag[0] == u'I':
-                versetype = u'Intro'
-            elif versetag[0] == u'P':
-                versetype = u'Prechorus'
-            elif versetag[0] == u'E':
-                versetype = u'Ending'
-            else:
-                versetype = u'Other'
-            sxml.add_verse_to_lyrics(versetype, versetag[1:], versetext)
-            song.search_lyrics += u' ' + self.remove_punctuation(versetext)
-        song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
-        song.verse_order = u' '.join(self.verse_order_list)
-        song.copyright = self.copyright
-        song.comment = self.comment 
-        song.theme_name = self.theme_name 
-        song.ccli_number = self.ccli_number 
-        for authortext in self.authors:
-            author = self.manager.get_author_by_name(authortext)
-            if author is None:
-                author = Author()
-                author.display_name = authortext
-                author.last_name = authortext.split(u' ')[-1]
-                author.first_name = u' '.join(authortext.split(u' ')[:-1])
-                self.manager.save_author(author)
-            song.authors.append(author)
-        if self.song_book_name:
-            song_book = self.manager.get_book_by_name(self.song_book_name)
-            if song_book is None:
-                song_book = Book()
-                song_book.name = self.song_book_name
-                song_book.publisher = self.song_book_pub
-                self.manager.save_book(song_book)
-            song.song_book_id = song_book.id
-        for topictext in self.topics:
-            topic = self.manager.get_topic_by_name(topictext)
-            if topic is None:
-                topic = Topic()
+            + '@' + self.alternate_title
+        song.song_number = self.song_number
+        song.search_lyrics = u''
+        sxml = SongXMLBuilder()
+        sxml.new_document()
+        sxml.add_lyrics_to_song()
+        for (versetag, versetext) in self.verses:
+            if versetag[0] == u'C':
+                versetype = u'Chorus'
+            elif versetag[0] == u'V':
+                versetype = u'Verse'
+            elif versetag[0] == u'B':
+                versetype = u'Bridge'
+            elif versetag[0] == u'I':
+                versetype = u'Intro'
+            elif versetag[0] == u'P':
+                versetype = u'Prechorus'
+            elif versetag[0] == u'E':
+                versetype = u'Ending'
+            else:
+                versetype = u'Other'
+            sxml.add_verse_to_lyrics(versetype, versetag[1:], versetext)
+            song.search_lyrics += u' ' + self.remove_punctuation(versetext)
+        song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
+        song.verse_order = u' '.join(self.verse_order_list)
+        song.copyright = self.copyright
+        song.comment = self.comment 
+        song.theme_name = self.theme_name 
+        song.ccli_number = self.ccli_number 
+        for authortext in self.authors:
+            author = self.manager.get_author_by_name(authortext)
+            if author is None:
+                author = Author()
+                author.display_name = authortext
+                author.last_name = authortext.split(u' ')[-1]
+                author.first_name = u' '.join(authortext.split(u' ')[:-1])
+                self.manager.save_author(author)
+            song.authors.append(author)
+        if self.song_book_name:
+            song_book = self.manager.get_book_by_name(self.song_book_name)
+            if song_book is None:
+                song_book = Book()
+                song_book.name = self.song_book_name
+                song_book.publisher = self.song_book_pub
+                self.manager.save_book(song_book)
+            song.song_book_id = song_book.id
+        for topictext in self.topics:
+            topic = self.manager.get_topic_by_name(topictext)
+            if topic is None:
+                topic = Topic()
                 topic.name = topictext
-                self.manager.save_topic(topic)
+                self.manager.save_topic(topic)
             song.topics.append(topictext)
-        self.manager.save_song(song)
-        
-    def print_song(self):
-        """ 
-        For debugging 
-        """
-        print u'========================================'   \
-            + u'========================================'
-        print u'TITLE: ' + self.title 
-        print u'ALT TITLE: ' + self.alternate_title 
-        for (versetag, versetext) in self.verses:
-            print u'VERSE ' + versetag + u': ' + versetext
-        print u'ORDER: ' + u' '.join(self.verse_order_list)
-        for author in self.authors:
-            print u'AUTHOR: ' + author
-        if self.copyright:
-            print u'COPYRIGHT: ' + self.copyright
-        if self.song_book_name:
-            print u'BOOK: ' + self.song_book_name
-        if self.song_book_pub:
-            print u'BOOK PUBLISHER: ' + self.song_book_pub
-        if self.song_number:
-            print u'NUMBER: ' + self.song_number
-        for topictext in self.topics:        
-            print u'TOPIC: ' + topictext
-        if self.comment:
-            print u'COMMENT: ' + self.comment
-        if self.theme_name:
-            print u'THEME: ' + self.theme_name
-        if self.ccli_number:
-            print u'CCLI: ' + self.ccli_number
-            
+        self.manager.save_song(song)
+        
+    def print_song(self):
+        """ 
+        For debugging 
+        """
+        print u'========================================'   \
+            + u'========================================'
+        print u'TITLE: ' + self.title 
+        print u'ALT TITLE: ' + self.alternate_title 
+        for (versetag, versetext) in self.verses:
+            print u'VERSE ' + versetag + u': ' + versetext
+        print u'ORDER: ' + u' '.join(self.verse_order_list)
+        for author in self.authors:
+            print u'AUTHOR: ' + author
+        if self.copyright:
+            print u'COPYRIGHT: ' + self.copyright
+        if self.song_book_name:
+            print u'BOOK: ' + self.song_book_name
+        if self.song_book_pub:
+            print u'BOOK PUBLISHER: ' + self.song_book_pub
+        if self.song_number:
+            print u'NUMBER: ' + self.song_number
+        for topictext in self.topics:        
+            print u'TOPIC: ' + topictext
+        if self.comment:
+            print u'COMMENT: ' + self.comment
+        if self.theme_name:
+            print u'THEME: ' + self.theme_name
+        if self.ccli_number:
+            print u'CCLI: ' + self.ccli_number
+            
 

=== modified file 'openlp/plugins/songs/songsplugin.py'
--- openlp/plugins/songs/songsplugin.py	2010-04-03 22:14:37 +0000
+++ openlp/plugins/songs/songsplugin.py	2010-04-13 07:39:21 +0000
@@ -29,7 +29,7 @@
 
 from openlp.core.lib import Plugin, build_icon, PluginStatus, Receiver
 from openlp.plugins.songs.lib import SongManager, SongMediaItem, SongsTab, \
-    SofImport
+    SofImport, OooImport
 from openlp.plugins.songs.forms import OpenLPImportForm, OpenSongExportForm, \
     OpenSongImportForm, OpenLPExportForm
 
@@ -105,11 +105,14 @@
         self.ImportOpenlp2Item.setObjectName(u'ImportOpenlp2Item')
         self.ImportSofItem = QtGui.QAction(import_menu)
         self.ImportSofItem.setObjectName(u'ImportSofItem')
+        self.ImportOooItem = QtGui.QAction(import_menu)
+        self.ImportOooItem.setObjectName(u'ImportOooItem')
         # Add to menus
         self.ImportSongMenu.addAction(self.ImportOpenlp1Item)
         self.ImportSongMenu.addAction(self.ImportOpenlp2Item)
         self.ImportSongMenu.addAction(self.ImportOpenSongItem)
         self.ImportSongMenu.addAction(self.ImportSofItem)
+        self.ImportSongMenu.addAction(self.ImportOooItem)
         import_menu.addAction(self.ImportSongMenu.menuAction())
         # Translations...
         self.ImportSongMenu.setTitle(import_menu.trUtf8('&Song'))
@@ -132,6 +135,12 @@
         self.ImportSofItem.setStatusTip(
             import_menu.trUtf8('Import songs from the VOLS1_2.RTF, sof3words' \
                 + '.rtf and sof4words.rtf supplied with the music books'))
+        self.ImportOooItem.setText(
+            import_menu.trUtf8('Generic Document/Presentation Import'))
+        self.ImportOooItem.setToolTip(
+            import_menu.trUtf8('Import songs from Word/Writer/Powerpoint/Impress'))
+        self.ImportOooItem.setStatusTip(
+            import_menu.trUtf8('Import songs from Word/Writer/Powerpoint/Impress'))
         # Signals and slots
         QtCore.QObject.connect(self.ImportOpenlp1Item,
             QtCore.SIGNAL(u'triggered()'), self.onImportOpenlp1ItemClick)
@@ -141,6 +150,8 @@
             QtCore.SIGNAL(u'triggered()'), self.onImportOpenSongItemClick)
         QtCore.QObject.connect(self.ImportSofItem,
             QtCore.SIGNAL(u'triggered()'), self.onImportSofItemClick)
+        QtCore.QObject.connect(self.ImportOooItem,
+            QtCore.SIGNAL(u'triggered()'), self.onImportOooItemClick)
         self.ImportSongMenu.menuAction().setVisible(False)
 
     def add_export_menu_item(self, export_menu):
@@ -184,12 +195,13 @@
         self.opensong_import_form.show()
 
     def onImportSofItemClick(self):
-        filename = QtGui.QFileDialog.getOpenFileName(
+        filenames = QtGui.QFileDialog.getOpenFileNames(
             None, self.trUtf8('Open Songs of Fellowship file'),
             u'', u'Songs of Fellowship file (*.rtf *.RTF)')
         try:
-            sofimport = SofImport(self.songmanager)        
-            sofimport.import_sof(unicode(filename))
+            for filename in filenames:
+                sofimport = SofImport(self.songmanager)        
+                sofimport.import_sof(unicode(filename))
         except:
             log.exception('Could not import SoF file')
             QtGui.QMessageBox.critical(None,
@@ -202,6 +214,14 @@
                 QtGui.QMessageBox.Ok)
         Receiver.send_message(u'load_song_list')
 
+    def onImportOooItemClick(self):
+        filenames = QtGui.QFileDialog.getOpenFileNames(
+            None, self.trUtf8('Open documents or presentations'),
+            u'', u'All Files(*.*)')
+        oooimport = OooImport(self.songmanager)        
+        oooimport.import_docs(filenames)
+        Receiver.send_message(u'load_song_list')
+
     def onExportOpenlp1ItemClicked(self):
         self.openlp_export_form.show()
 


Follow ups