← Back to team overview

openlp-core team mailing list archive

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

 

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

Requested reviews:
    openlp.org Core (openlp-core)

Mixed bag of changes - Sorry.
Fixed up the song migration code from 1.x to 2 format including getting round SqlAlchemy limitations in 1.x format.
Fixed bug in Theme caused by Unicode work.  Import Themes now works again.
Fixed ThemeManager bugs including allowing any file name to be imported for Themes.
Fixed niggle in Topic where Save was disabled. 
Start of Presentations work.
-- 
https://code.launchpad.net/~trb143/openlp/servicing2/+merge/7835
Your team openlp.org Core is subscribed to branch lp:openlp.
=== added file 'cnvdb.py'
--- cnvdb.py	1970-01-01 00:00:00 +0000
+++ cnvdb.py	2009-06-23 16:25:40 +0000
@@ -0,0 +1,23 @@
+import codecs
+
+
+class Convert():
+    def __init__(self):
+        pass
+
+    def process(self, inname, outname):
+        infile = codecs.open(inname, 'r', encoding='iso-8859-1')
+        writefile = codecs.open(outname, 'w', encoding='utf-8')
+        count = 0
+        for line in infile:
+            writefile.write(line)
+            if count < 150:
+                print line
+                count += 1
+        infile.close()
+        writefile.close()
+
+
+if __name__ == '__main__':
+    mig = Convert()
+    mig.process(u'/home/timali/.local/share/openlp/songs/songs.dmp',u'/home/timali/.local/share/openlp/songs/songs.dmp2')

=== modified file 'openlp/core/lib/themexmlhandler.py'
--- openlp/core/lib/themexmlhandler.py	2009-05-22 05:14:55 +0000
+++ openlp/core/lib/themexmlhandler.py	2009-06-24 05:17:41 +0000
@@ -16,8 +16,6 @@
 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
-from xml.dom.minidom import  Document
-from xml.etree.ElementTree import ElementTree, XML, dump
 
 For XML Schema see wiki.openlp.org
 """
@@ -256,5 +254,5 @@
         s = u''
         for k in dir(self):
             if k[0:1] != u'_':
-                s += u'%30s : %s\n' %(k,getattr(self,k))
+                s += u'%30s : %s\n' %(k, getattr(self, k))
         return s

=== modified file 'openlp/core/theme/theme.py'
--- openlp/core/theme/theme.py	2009-06-16 18:21:24 +0000
+++ openlp/core/theme/theme.py	2009-06-24 05:17:41 +0000
@@ -1,9 +1,26 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
+"""
+OpenLP - Open Source Lyrics Projection
+Copyright (c) 2008 Raoul Snyman
+Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley, 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 platform
-ver = platform.python_version()
-if ver >= '2.5':
-	from xml.etree.ElementTree import ElementTree, XML
-else:
-	from elementtree import ElementTree, XML
+import types
+from xml.etree.ElementTree import ElementTree, XML
 
 from PyQt4 import QtGui
 
@@ -59,7 +76,7 @@
           FontName       : name of font to use
           FontColor      : color for main font
           FontProportion : size of font
-	  FontUnits      : whether size of font is in <pixels> or <points>
+          FontUnits      : whether size of font is in <pixels> or <points>
 
           Shadow       : 0 - no shadow, non-zero use shadow
           ShadowColor  : color for drop shadow
@@ -78,52 +95,57 @@
         # init to defaults
         self._set_from_XML(blankstylexml)
         self._set_from_XML(xml)
+#        print self.__str__()
 
     def _get_as_string(self):
-        s=""
+        s = u''
         keys=dir(self)
         keys.sort()
         for k in keys:
-            if k[0:1] != "_":
-                s+= "_%s_" %(getattr(self,k))
+            if k[0:1] != u'_':
+                s += u'_%s_' %(getattr(self,k))
         return s
+
     def _set_from_XML(self, xml):
-        root=ElementTree(element=XML(xml))
-        iter=root.getiterator()
+        root = ElementTree(element=XML(xml))
+        iter = root.getiterator()
         for element in iter:
-            if element.tag != "Theme":
-                t=element.text
-#                 print element.tag, t, type(t)
-                if type(t) == type(None): # easy!
-                    val=t
-                if type(t) == type(u' '): # strings need special handling to sort the colours out
-#                    print "str",
-                    if t[0] == "$": # might be a hex number
-#                        print "hex",
+            if element.tag != u'Theme':
+                t = element.text
+#                print element.tag, t, type(t)
+                val = 0
+                # easy!
+                if type(t) == type(None):
+                    val = t
+                # strings need special handling to sort the colours out
+                if type(t) is types.StringType or type(t) is types.UnicodeType:
+#                    print u'str',
+                    if t[0] == u'$': # might be a hex number
+#                        print u'hex',
                         try:
-                            val=int(t[1:], 16)
+                            val = int(t[1:], 16)
                         except ValueError: # nope
-#                            print "nope",
+#                            print u'nope'
                             pass
                     elif DelphiColors.has_key(t):
-#                        print "colour",
-                        val=DelphiColors[t]
+#                        print u'colour ', t
+                        val = DelphiColors[t]
                     else:
                         try:
-                            val=int(t)
+                            val = int(t)
                         except ValueError:
-                            val=t
+                            val = t
                 if (element.tag.find(u'Color') > 0 or
                     (element.tag.find(u'BackgroundParameter') == 0 and type(val) == type(0))):
                     # convert to a wx.Colour
                     val= QtGui.QColor((val>>16) & 0xFF, (val>>8)&0xFF, val&0xFF)
- #               print [val]
-                setattr(self,element.tag, val)
-
+#                    print [val]
+#                print u'>> ', element.tag, val
+                setattr(self, element.tag, val)
 
     def __str__(self):
-        s=""
+        s = u''
         for k in dir(self):
-            if k[0:1] != "_":
-                s+= "%30s : %s\n" %(k,getattr(self,k))
-        return s
\ No newline at end of file
+            if k[0:1] != u'_':
+                s += u'%30s : %s\n' %(k, getattr(self, k))
+        return s

=== modified file 'openlp/core/ui/slidecontroller.py'
--- openlp/core/ui/slidecontroller.py	2009-06-21 19:41:01 +0000
+++ openlp/core/ui/slidecontroller.py	2009-06-23 16:25:40 +0000
@@ -231,11 +231,6 @@
             QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected)
         QtCore.QObject.connect(self.PreviewListView,
             QtCore.SIGNAL(u'activated(QModelIndex)'), self.onSlideSelected)
-        QtCore.QObject.connect(self.PreviewListView,
-            QtCore.SIGNAL(u'entered(QModelIndex)'), self.onTest)
-
-    def onTest(self ,  item):
-        print "found", item
 
     def onSlideSelectedFirst(self):
         """

=== modified file 'openlp/core/ui/thememanager.py'
--- openlp/core/ui/thememanager.py	2009-06-20 19:11:17 +0000
+++ openlp/core/ui/thememanager.py	2009-06-24 05:17:41 +0000
@@ -57,9 +57,9 @@
 
     def insertRow(self, row, filename):
         self.beginInsertRows(QtCore.QModelIndex(), row, row)
-        log.info(u'insert row %d:%s' % (row, filename))
+        log.debug(u'insert row %d:%s' % (row, filename))
         (prefix, shortfilename) = os.path.split(unicode(filename))
-        log.info(u'shortfilename = %s' % shortfilename)
+        log.debug(u'shortfilename = %s' % shortfilename)
         theme = shortfilename.split(u'.')
         # create a preview image
         if os.path.exists(filename):
@@ -81,7 +81,7 @@
             pixmap.fill(QtCore.Qt.black)
         # finally create the row
         self.items.insert(row, (filename, pixmap, shortfilename, theme[0]))
-        log.info(u'Items: %s' % self.items)
+        log.debug(u'Items: %s' % self.items)
         self.endInsertRows()
 
     def removeRow(self, row):
@@ -190,8 +190,13 @@
         try:
             os.remove(os.path.join(self.path, th))
         except:
-            pass #if not present do not worry
-        shutil.rmtree(os.path.join(self.path, theme))
+            #if not present do not worry
+            pass
+        try:
+            shutil.rmtree(os.path.join(self.path, theme))
+        except:
+            #if not present do not worry
+            pass
         self.themeData.clearItems()
         self.loadThemes()
 
@@ -201,7 +206,7 @@
     def onImportTheme(self):
         files = QtGui.QFileDialog.getOpenFileNames(None,
             translate(u'ThemeManager', u'Select Theme Import File'),
-            self.path, u'Theme (*.theme)')
+            self.path, u'Theme (*.*)')
         log.info(u'New Themes %s', unicode(files))
         if len(files) > 0:
             for file in files:
@@ -335,7 +340,7 @@
         outfile = open(theme_file, u'w')
         outfile.write(theme_xml)
         outfile.close()
-        if image_from is not None and image_from is not image_to:
+        if image_from is not None and image_from != image_to:
             shutil.copyfile(image_from,  image_to)
         self.generateAndSaveImage(self.path, name, theme_xml)
         self.themeData.clearItems()

=== modified file 'openlp/migration/display.py'
--- openlp/migration/display.py	2009-06-16 18:21:24 +0000
+++ openlp/migration/display.py	2009-06-23 16:25:40 +0000
@@ -22,14 +22,14 @@
     global log
     log=logging.getLogger(u'Display Logger')
     log.info(u'Display Class loaded')
-    
+
     @staticmethod
     def output(string):
         log.debug(string);
         print (string)
-        
+
     @staticmethod
     def sub_output(string):
         if not string == None:
-            log.debug(u'   "+string);
-            print (u'   "+string)        
\ No newline at end of file
+            log.debug(u'   '+string);
+            print (u'   '+string)

=== modified file 'openlp/migration/migratefiles.py'
--- openlp/migration/migratefiles.py	2009-06-16 18:21:24 +0000
+++ openlp/migration/migratefiles.py	2009-06-23 16:25:40 +0000
@@ -24,18 +24,18 @@
     def process(self):
         self.display.output(u'Files process started');
         self._initial_setup()
-        self.display.output(u'Files process finished');        
-        
+        self.display.output(u'Files process finished');
+
     def _initial_setup(self):
         self.display.output(u'Initial Setup started');
         ConfigHelper.get_data_path()
-        self.display.sub_output(u'Config created');        
-        ConfigHelper.get_config(u'bible", u'data path')
-        self.display.sub_output(u'Config created');        
-        ConfigHelper.get_config(u'videos", u'data path') 
-        self.display.sub_output(u'videos created');                
-        ConfigHelper.get_config(u'images", u'data path') 
-        self.display.sub_output(u'images created');                
-        ConfigHelper.get_config(u'presentations", u'data path') 
-        self.display.sub_output(u'presentations created');                
-        self.display.output(u'Initial Setup finished');        
\ No newline at end of file
+        self.display.sub_output(u'Config created');
+        ConfigHelper.get_config(u'bible', u'data path')
+        self.display.sub_output(u'Config created');
+        ConfigHelper.get_config(u'videos', u'data path')
+        self.display.sub_output(u'videos created');
+        ConfigHelper.get_config(u'images', u'data path')
+        self.display.sub_output(u'images created');
+        ConfigHelper.get_config(u'presentations', u'data path')
+        self.display.sub_output(u'presentations created');
+        self.display.output(u'Initial Setup finished');

=== modified file 'openlp/migration/migratesongs.py'
--- openlp/migration/migratesongs.py	2009-06-16 18:21:24 +0000
+++ openlp/migration/migratesongs.py	2009-06-24 06:11:04 +0000
@@ -16,6 +16,7 @@
 Place, Suite 330, Boston, MA 02111-1307 USA
 """
 import os
+import sys
 import logging
 import sqlite3
 from openlp.core.lib import PluginConfig
@@ -24,20 +25,81 @@
 from sqlalchemy.sql import select
 from sqlalchemy import create_engine
 from sqlalchemy.orm import scoped_session, sessionmaker, mapper, relation, clear_mappers
-
+from openlp.plugins.songs.lib.models import metadata, session, \
+    engine, songs_table, Song, Author, Topic,  Book
 from openlp.plugins.songs.lib.tables import *
 from openlp.plugins.songs.lib.classes import *
 
-clear_mappers()
-mapper(Author, authors_table)
-mapper(Book, song_books_table)
-mapper(Song, songs_table, properties={
-        'authors': relation(Author, backref='songs',
-        secondary=authors_songs_table),
-        'book': relation(Book, backref='songs'),
-        'topics': relation(Topic, backref='songs',
-        secondary=songs_topics_table)})
-mapper(Topic, topics_table)
+def init_models(url):
+    engine = create_engine(url)
+    metadata.bind = engine
+    session = scoped_session(sessionmaker(autoflush=True, autocommit=False,
+                                          bind=engine))
+    mapper(Author, authors_table)
+    mapper(TAuthor, temp_authors_table)
+    mapper(Book, song_books_table)
+    mapper(Song, songs_table,
+       properties={'authors': relation(Author, backref='songs',
+                                       secondary=authors_songs_table),
+                   'book': relation(Book, backref='songs'),
+                   'topics': relation(Topic, backref='songs',
+                                      secondary=songs_topics_table)})
+    mapper(TSong, temp_songs_table)
+    mapper(TSongAuthor, temp_authors_songs_table)
+    mapper(Topic, topics_table)
+    return session
+
+temp_authors_table = Table(u'authors_temp', metadata,
+    Column(u'authorid', types.Integer,  primary_key=True),
+    Column(u'authorname', String(40))
+)
+
+temp_songs_table = Table(u'songs_temp', metadata,
+    Column(u'songid', types.Integer, primary_key=True),
+    Column(u'songtitle', String(60)),
+    Column(u'lyrics', types.UnicodeText),
+    Column(u'copyrightinfo', String(255)),
+    Column(u'settingsid', types.Integer)
+)
+
+# Definition of the "authors_songs" table
+temp_authors_songs_table = Table(u'songauthors_temp', metadata,
+    Column(u'authorid', types.Integer, primary_key=True),
+    Column(u'songid', types.Integer)
+)
+class BaseModel(object):
+    """
+    BaseModel provides a base object with a set of generic functions
+    """
+
+    @classmethod
+    def populate(cls, **kwargs):
+        """
+        Creates an instance of a class and populates it, returning the instance
+        """
+        me = cls()
+        keys = kwargs.keys()
+        for key in keys:
+            me.__setattr__(key, kwargs[key])
+        return me
+
+class TAuthor(BaseModel):
+    """
+    Author model
+    """
+    pass
+
+class TSong(BaseModel):
+    """
+    Author model
+    """
+    pass
+
+class TSongAuthor(BaseModel):
+    """
+    Author model
+    """
+    pass
 
 class MigrateSongs():
     def __init__(self, display):
@@ -55,186 +117,70 @@
 
     def v_1_9_0(self, database):
         self.display.output(u'Migration 1.9.0 Started for ' + database)
-        self._v1_9_0_authors(database)
-        self._v1_9_0_topics(database)
-        self._v1_9_0_songbook(database)
-        self._v1_9_0_songauthors(database)
-        self._v1_9_0_songtopics(database)
-        self._v1_9_0_songs(database)
+        self._v1_9_0_old(database)
+        self._v1_9_0_new(database)
+        self._v1_9_0_cleanup(database)
         self.display.output(u'Migration 1.9.0 Finished for ' + database)
 
-    def _v1_9_0_authors(self, database):
-        self.display.sub_output(u'Authors Started for ' + database)
-        conn = sqlite3.connect(self.data_path + os.sep + database)
-        conn.execute(u'""alter table authors rename to authors_temp;""')
-        conn.commit()
-        self.display.sub_output(u'old author renamed to author_temp')
-        conn.execute(u'""create table authors (
-            id integer primary key ASC AUTOINCREMENT,
-            first_name varchar(128),
-            last_name varchar(128),
-            display_name varchar(255)
-            );""')
-        conn.commit()
-        self.display.sub_output(u'authors table created')
-        conn.execute(u'""create index if not exists author1 on authors 
-            (display_name ASC,id ASC);""')
-        conn.commit()
-        self.display.sub_output(u'index author1 created')
-        conn.execute(u'""create index if not exists author2 on authors 
-            (last_name ASC,id ASC);""')
-        conn.commit()
-        self.display.sub_output(u'index author2 created')
-        conn.execute(u'""create index if not exists author3 on authors 
-            (first_name ASC,id ASC);""')
-        conn.commit()
-        self.display.sub_output(u'index author3 created')
-        self.display.sub_output(u'Author Data Migration started')
-        conn.execute(u'""insert into authors (id, display_name) 
-            select authorid, authorname from authors_temp;""')
-        conn.commit()
-        self.display.sub_output(u'authors populated')
-        c = conn.cursor()        
-        text = c.execute(u'""select * from authors""') .fetchall()
-        for author in text:
-            dispname = author[3]
-            dispname = dispname.replace(u''", u'') 
-            pos = dispname.rfind(u' ')
-            authorfirstname = dispname[:pos]
-            authorlastname = dispname[pos + 1:len(dispname)]
-            s = "update authors set first_name = '" \
-                + authorfirstname + "', last_name = '" + authorlastname \
-                + "' where id = " + unicode(author[0])
-            c.execute(s)
-        conn.commit()
-        self.display.sub_output(u'Author Data Migration Completed')
-        conn.execute(u'""drop table authors_temp;""')
-        conn.commit()
-        conn.close()
-        self.display.sub_output(u'author_temp dropped')
-        self.display.sub_output(u'Authors Completed')
-
-    def _v1_9_0_songbook(self, database):
-        self.display.sub_output(u'SongBook Started for ' + database)
-        conn = sqlite3.connect(self.data_path + os.sep + database)
-        conn.execute(u'""create table if not exists song_books (
-            id integer Primary Key ASC AUTOINCREMENT,
-            name varchar(128),
-            publisher varchar(128)
-            );""')
-        conn.commit()
-        self.display.sub_output(u'songbook table created')
-        conn.execute(u'""create index if not exists songbook1 on song_books (name ASC,id ASC);""')
-        conn.commit()
-        self.display.sub_output(u'index songbook1 created')
-        conn.execute(u'""create index if not exists songbook2 on song_books (publisher ASC,id ASC);""')
-        conn.commit()
-        conn.close()
-        self.display.sub_output(u'index songbook2 created')
-        self.display.sub_output(u'SongBook Completed')
-
-    def _v1_9_0_songs(self, database):
-        self.display.sub_output(u'Songs Started for ' + database)
-        conn = sqlite3.connect(self.data_path + os.sep + database)
-        conn.execute(u'""alter table songs rename to songs_temp;""')
-        conn.commit()
-        conn.execute(u'""create table if not exists songs  (
-            id integer Primary Key ASC AUTOINCREMENT,
-            song_book_id integer,
-            title varchar(255),
-            lyrics text,
-            verse_order varchar(128),
-            copyright varchar(255),
-            comments text,
-            ccli_number varchar(64),
-            song_number varchar(64),
-            theme_name varchar(128),
-            search_title varchar(255),
-            search_lyrics text
-            );""')
-        conn.commit()
-        self.display.sub_output(u'songs table created')
-        conn.execute(u'""create index if not exists songs1 on songs 
-            (search_lyrics ASC,id ASC);""')
-        conn.commit()
-        self.display.sub_output(u'index songs1 created')
-        conn.execute(u'""create index if not exists songs2 on songs 
-            (search_title ASC,id ASC);""')
-        conn.commit()
-        self.display.sub_output(u'index songs2 created')
-        conn.execute(u'""insert into songs (id, title, lyrics, copyright,
-            search_title, search_lyrics, song_book_id) 
-            select songid,  songtitle, lyrics, copyrightinfo, 
+    def _v1_9_0_old(self, database):
+        self.display.sub_output(u'Rename Tables ' + database)
+        conn = sqlite3.connect(self.data_path + os.sep + database)
+        conn.execute(u'alter table authors rename to authors_temp;')
+        conn.commit()
+        conn.execute(u'alter table songs rename to songs_temp;')
+        conn.commit()
+        conn.execute(u'alter table songauthors rename to songauthors_temp;')
+        conn.commit()
+
+    def _v1_9_0_new(self, database):
+        self.display.sub_output(u'Create new Tables ' + database)
+        self.db_url = u'sqlite:///' + self.data_path + u'/songs.sqlite'
+        print self.db_url
+        self.session = init_models(self.db_url)
+        if not songs_table.exists():
+            metadata.create_all()
+        results = self.session.query(TSong).order_by(TSong.songid).all()
+        for songs_temp in results:
+            song = Song()
+            song.title = songs_temp.songtitle
+            song.lyrics = songs_temp.lyrics.replace(u'\r\n', u'\n')
+            song.copyright = songs_temp.copyrightinfo
+            song.search_title = u''
+            song.search_lyrics = u''
+            print songs_temp.songtitle
+            aa  = self.session.execute(u'select * from songauthors_temp where songid =' + unicode(songs_temp.songid) )
+            for row in aa:
+                a = row['authorid']
+                author = Author()
+                authors_temp = self.session.query(TAuthor).get(a)
+                author.display_name =  authors_temp.authorname
+                song.authors.append(author)
+            try:
+                self.session.add(song)
+                self.session.commit()
+            except:
+                self.session.rollback()
+                print u'Errow thrown = ', sys.exc_info()[1]
+
+    def _v1_9_0_cleanup(self, database):
+        self.display.sub_output(u'Update Internal Data ' + database)
+        conn = sqlite3.connect(self.data_path + os.sep + database)
+        conn.execute("""update songs set search_title =
             replace(replace(replace(replace(replace(replace(replace(replace(
-            replace(songtitle,  '&', 'and'), ',', ''), ';', ''), ':', ''), 
-            '(u', ''), ')', ''), '{', ''), '}',''),'?',''), 
+            replace(title,  '&', 'and'), ',', ''), ';', ''), ':', ''),
+            '(u', ''), ')', ''), '{', ''), '}',''),'?','');""")
+        conn.execute("""update songs set search_lyrics =
             replace(replace(replace(replace(replace(replace(replace(replace(
             replace(lyrics,  '&', 'and'), ',', ''), ';', ''), ':', ''),
-            '(u', ''), ')', ''), '{', ''), '}',''),'?',''),
-            0
-            from songs_temp;""')
-        conn.commit()
-        self.display.sub_output(u'songs populated')
-        conn.execute(u'""drop table songs_temp;""')
-        conn.commit()
-        conn.close()
-        self.display.sub_output(u'songs_temp dropped')
-        self.display.sub_output(u'Songs Completed')
-
-    def _v1_9_0_topics(self, database):
-        self.display.sub_output(u'Topics Started for ' + database)
-        conn = sqlite3.connect(self.data_path+os.sep+database)
-        conn.text_factory = str
-        conn.execute(u'""create table if not exists topics 
-            (id integer Primary Key ASC AUTOINCREMENT,
-            name varchar(128));""')
-        conn.commit()
-        self.display.sub_output(u'Topic table created')
-        conn.execute(u'""create index if not exists topic1 on topics (name ASC,id ASC);""')
-        conn.commit()
-        conn.close()
-        self.display.sub_output(u'index topic1 created')
-
-        self.display.sub_output(u'Topics Completed')
-
-    def _v1_9_0_songauthors(self, database):
-        self.display.sub_output(u'SongAuthors Started for ' + database);
-        conn = sqlite3.connect(self.data_path + os.sep + database)
-        conn.execute(u'""create table if not exists authors_songs 
-            (author_id integer,
-            song_id integer);""')
-        conn.commit()
-        self.display.sub_output(u'authors_songs table created')
-        conn.execute(u'""insert into authors_songs (author_id, song_id) 
-            select authorid, songid from songauthors;""')
-        conn.commit()
-        self.display.sub_output(u'authors_songs populated')
-        conn.execute(u'""drop table songauthors;""')
-        conn.commit()
-        self.display.sub_output(u'songauthors dropped')
-        conn.close()
-        self.display.sub_output(u'SongAuthors Completed')
-
-    def _v1_9_0_songtopics(self, database):
-        self.display.sub_output(u'Songtopics Started for ' + database);
-        conn = sqlite3.connect(self.data_path+os.sep+database)
-        conn.execute(u'""create table if not exists song_topics 
-            (song_id integer,
-            topic_id integer);""')
-        conn.commit()
-        self.display.sub_output(u'songtopics table created')
-        conn.execute(u'""create index if not exists songtopic1 on song_topics (topic_id ASC,song_id ASC);""')
-        conn.commit()
-        self.display.sub_output(u'index songtopic1 created')
-        conn.execute(u'""create index if not exists songtopic2 on song_topics (song_id ASC,topic_id ASC);""')
-        conn.commit()
-        conn.close()
-        self.display.sub_output(u'index songtopic2 created')
-        self.display.sub_output(u'SongTopics Completed')
-
-    def run_cmd(self, cmd):
-        filein, fileout  = os.popen4(cmd)
-        out = fileout.readlines()
-        if len(out) > 0:
-            for o in range (0, len(out)):
-                self.display.sub_output(out[o])
\ No newline at end of file
+            '(u', ''), ')', ''), '{', ''), '}',''),'?','')
+            ;""")
+        conn.commit()
+        conn.execute(u'drop table authors_temp;')
+        conn.commit()
+        conn.execute(u'drop table songs_temp;')
+        conn.commit()
+        conn.execute(u'drop table songauthors_temp;')
+        conn.commit()
+        conn.execute(u'drop table settings;')
+
+        conn.commit()

=== modified file 'openlp/plugins/bibles/lib/mediaitem.py'
--- openlp/plugins/bibles/lib/mediaitem.py	2009-06-17 05:11:16 +0000
+++ openlp/plugins/bibles/lib/mediaitem.py	2009-06-23 16:25:40 +0000
@@ -45,7 +45,6 @@
         if dropAction == QtCore.Qt.CopyAction:
             self.close()
 
-
 class BibleMediaItem(MediaManagerItem):
     """
     This is the custom media manager item for Bibles.

=== modified file 'openlp/plugins/presentations/lib/impresscom.py'
--- openlp/plugins/presentations/lib/impresscom.py	2009-06-16 18:21:24 +0000
+++ openlp/plugins/presentations/lib/impresscom.py	2009-06-23 16:25:40 +0000
@@ -1,4 +1,4 @@
-from win32com.client import Dispatch
+#from win32com.client import Dispatch
 
 # OOo API documentation:
 # http://api.openoffice.org/docs/common/ref/com/sun/star/presentation/XSlideShowController.html
@@ -33,26 +33,26 @@
         self._app.Terminate()
         self._app = None
         self._sm = None
-        
+
 class ImpressCOMPres(object):
     def __init__(self, oooApp, filename):
         self.oooApp = oooApp
         self.filename = filename
         self.open()
-        
+
     def getPres(self):
         if self._pres == None:
             self.open()
         return self._pres
-        
+
     pres = property(getPres)
-    
+
     def open(self):
-        self.comp = self.oooApp.app.loadComponentFromURL(u'file:///" + self.filename, "_blank", 0, []) 
+        self.comp = self.oooApp.app.loadComponentFromURL(u'file:///' + self.filename, '_blank', 0, [])
         self.presdoc = self.comp.getPresentation()
         self.presdoc.start()
         self._pres = self.presdoc.getController()
-        
+
     def close(self):
         self.pres.deactivate()
         self.presdoc.end()
@@ -63,7 +63,7 @@
 
     def isActive(self):
         return self.pres.isRunning() and self.pres.isActive()
- 
+
     def resume(self):
         return self.pres.resume()
 
@@ -72,7 +72,7 @@
 
     def blankScreen(self):
         self.pres.blankScreen(0)
-    
+
     def stop(self):
         self.pres.deactivate()
         # self.presdoc.end()
@@ -83,7 +83,7 @@
 
     def getSlideNumber(self):
         return self.pres.getCurrentSlideIndex
-        
+
     def setSlideNumber(self, slideno):
         self.pres.gotoSlideIndex(slideno)
 
@@ -112,7 +112,7 @@
 
 if __name__ == '__main__':
     ooo = ImpressCOMApp()
-    show = ImpressCOMPres(ooo, "c:/test1.ppt')
+    show = ImpressCOMPres(ooo, u'c:/test1.ppt')
     show.go()
     show.resume()
-    show.nextStep()
\ No newline at end of file
+    show.nextStep()

=== modified file 'openlp/plugins/songs/forms/topicsform.py'
--- openlp/plugins/songs/forms/topicsform.py	2009-06-14 15:12:40 +0000
+++ openlp/plugins/songs/forms/topicsform.py	2009-06-24 06:15:04 +0000
@@ -51,7 +51,8 @@
         Refresh the screen and rest fields
         """
         self.TopicsListWidget.clear()
-        self.onClearButtonClick() # tidy up screen
+        # tidy up screen
+        self.onClearButtonClick()
         topics = self.songmanager.get_topics()
         for topic in topics:
             topic_name = QtGui.QListWidgetItem(topic.name)
@@ -77,12 +78,13 @@
         """
         Sent New or update details to the database
         """
-        if self.topic == None:
-            self.topic = Topic()
-        self.topic.name = unicode(self.TopicNameEdit.displayText())
-        self.songmanager.save_topic(self.topic)
-        self.onClearButtonClick()
-        self.load_form()
+        if self._validate_form():
+            if self.topic == None:
+                self.topic = Topic()
+            self.topic.name = unicode(self.TopicNameEdit.displayText())
+            self.songmanager.save_topic(self.topic)
+            self.onClearButtonClick()
+            self.load_form()
 
     def onClearButtonClick(self):
         """
@@ -91,7 +93,6 @@
         self.TopicNameEdit.setText(u'')
         self.MessageLabel.setText(u'')
         self.DeleteButton.setEnabled(False)
-        self.AddUpdateButton.setEnabled(True)
         self.topic = None
         self._validate_form()
 
@@ -115,7 +116,10 @@
 
     def _validate_form(self):
         # We need at lease a display name
+        valid = True
         if len(self.TopicNameEdit.displayText()) == 0:
-            self.AddUpdateButton.setEnabled(False)
+            valid = False
+            self.TopicNameEdit.setStyleSheet(u'background-color: red; color: white')
         else:
-            self.AddUpdateButton.setEnabled(True)
+            self.TopicNameEdit.setStyleSheet(u'')
+        return valid

=== modified file 'openlp/plugins/songs/lib/tables.py'
--- openlp/plugins/songs/lib/tables.py	2009-06-16 18:21:24 +0000
+++ openlp/plugins/songs/lib/tables.py	2009-06-24 06:10:13 +0000
@@ -16,7 +16,7 @@
 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 Place, Suite 330, Boston, MA 02111-1307 USA
 """
-
+from sqlalchemy import  *
 from sqlalchemy import Column, Table, ForeignKey, types
 
 from openlp.plugins.songs.lib.meta import metadata
@@ -68,4 +68,13 @@
 songs_topics_table = Table(u'songs_topics', metadata,
     Column(u'song_id', types.Integer, ForeignKey(u'songs.id'), primary_key=True),
     Column(u'topic_id', types.Integer, ForeignKey(u'topics.id'), primary_key=True)
-)
\ No newline at end of file
+)
+Index(u'authors_id',authors_table.c.id)
+Index(u'authors_display_name_id',authors_table.c.display_name, authors_table.c.id)
+Index(u'song_books_id',song_books_table.c.id)
+Index(u'songs_id',songs_table.c.id)
+Index(u'topics_id',topics_table.c.id)
+Index(u'authors_songs_author',authors_songs_table.c.author_id, authors_songs_table.c.song_id)
+Index(u'authors_songs_song',authors_songs_table.c.song_id, authors_songs_table.c.author_id)
+Index(u'topics_song_topic', songs_topics_table.c.topic_id, songs_topics_table.c.song_id)
+Index(u'topics_song_song',songs_topics_table.c.song_id, songs_topics_table.c.topic_id)

=== modified file 'openlpcnv.pyw'
--- openlpcnv.pyw	2009-06-16 18:21:24 +0000
+++ openlpcnv.pyw	2009-06-23 16:25:40 +0000
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 
-import os 
+import os
 import sys
 import logging
 import time
@@ -21,25 +21,25 @@
     def __init__(self):
         """
         """
-        self.display = Display()        
-        self.stime =  time.strftime(u'%Y-%m-%d-%H%M%S", time.localtime())
-        self.display.output(u'OpenLp v1.9.0 Migration Utility Started" )
-        
+        self.display = Display()
+        self.stime =  time.strftime(u'%Y-%m-%d-%H%M%S', time.localtime())
+        self.display.output(u'OpenLp v1.9.0 Migration Utility Started')
+
     def process(self):
-        MigrateFiles(self.display).process()
+        #MigrateFiles(self.display).process()
         MigrateSongs(self.display).process()
-        MigrateBibles(self.display).process()        
-        
+        #MigrateBibles(self.display).process()
+
     def move_log_file(self):
         fname = 'openlp-migration.log'
         c = os.path.splitext(fname)
         b = (c[0]+'-'+ unicode(self.stime) + c[1])
-        self.display.output(u'Logfile " +b + " generated')       
+        self.display.output(u'Logfile " +b + " generated')
         self.display.output(u'Migration Utility Finished ')
-        os.rename(fname, b)        
-
-        
+        os.rename(fname, b)
+
+
 if __name__ == '__main__':
     mig = Migration()
     mig.process()
-    #mig.move_log_file()
\ No newline at end of file
+    #mig.move_log_file()