← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~raoul-snyman/openlp/song-audio into lp:openlp

 

Raoul Snyman has proposed merging lp:~raoul-snyman/openlp/song-audio into lp:openlp.

Requested reviews:
  OpenLP Core (openlp-core)

For more details, see:
https://code.launchpad.net/~raoul-snyman/openlp/song-audio/+merge/75062

A few fixes and enhancements to the song audio stuff to make it minimally useful:

 - Fixed up the openlp.org 1.2.x import process on Windows to copy the files across
   (does nothing on other platforms)
 - Added an option to start the background audio paused
   (on by default)
-- 
https://code.launchpad.net/~raoul-snyman/openlp/song-audio/+merge/75062
Your team OpenLP Core is requested to review the proposed merge of lp:~raoul-snyman/openlp/song-audio into lp:openlp.
=== modified file 'openlp/core/ui/generaltab.py'
--- openlp/core/ui/generaltab.py	2011-07-11 16:32:25 +0000
+++ openlp/core/ui/generaltab.py	2011-09-12 20:09:26 +0000
@@ -170,6 +170,15 @@
         self.customHeightValueEdit.setMaximum(9999)
         self.displayLayout.addWidget(self.customHeightValueEdit, 4, 3)
         self.rightLayout.addWidget(self.displayGroupBox)
+        # Background audio
+        self.audioGroupBox = QtGui.QGroupBox(self.rightColumn)
+        self.audioGroupBox.setObjectName(u'audioGroupBox')
+        self.audioLayout = QtGui.QVBoxLayout(self.audioGroupBox)
+        self.audioLayout.setObjectName(u'audioLayout')
+        self.startPausedCheckBox = QtGui.QCheckBox(self.audioGroupBox)
+        self.startPausedCheckBox.setObjectName(u'startPausedCheckBox')
+        self.audioLayout.addWidget(self.startPausedCheckBox)
+        self.rightLayout.addWidget(self.audioGroupBox)
         self.rightLayout.addStretch()
         # Signals and slots
         QtCore.QObject.connect(self.overrideCheckBox,
@@ -243,6 +252,10 @@
         self.customYLabel.setText(translate('OpenLP.GeneralTab', 'Y'))
         self.customHeightLabel.setText(translate('OpenLP.GeneralTab', 'Height'))
         self.customWidthLabel.setText(translate('OpenLP.GeneralTab', 'Width'))
+        self.audioGroupBox.setTitle(
+            translate('OpenLP.GeneralTab', 'Background Audio'))
+        self.startPausedCheckBox.setText(
+            translate('OpenLP.GeneralTab', 'Start background audio paused'))
 
     def load(self):
         """
@@ -290,6 +303,8 @@
             QtCore.QVariant(self.screens.current[u'size'].height())).toInt()[0])
         self.customWidthValueEdit.setValue(settings.value(u'width',
             QtCore.QVariant(self.screens.current[u'size'].width())).toInt()[0])
+        self.startPausedCheckBox.setChecked(settings.value(
+            u'audio start paused', QtCore.QVariant(True)).toBool())
         settings.endGroup()
         self.customXValueEdit.setEnabled(self.overrideCheckBox.isChecked())
         self.customYValueEdit.setEnabled(self.overrideCheckBox.isChecked())
@@ -341,6 +356,8 @@
             QtCore.QVariant(self.customWidthValueEdit.value()))
         settings.setValue(u'override position',
             QtCore.QVariant(self.overrideCheckBox.isChecked()))
+        settings.setValue(u'audio start paused',
+            QtCore.QVariant(self.startPausedCheckBox.isChecked()))
         settings.endGroup()
         # On save update the screens as well
         self.postSetUp(True)

=== modified file 'openlp/core/ui/slidecontroller.py'
--- openlp/core/ui/slidecontroller.py	2011-09-06 19:32:30 +0000
+++ openlp/core/ui/slidecontroller.py	2011-09-12 20:09:26 +0000
@@ -633,7 +633,14 @@
                 log.debug(u'Starting to play...')
                 self.display.audioPlayer.addToPlaylist(
                     self.serviceItem.background_audio)
-                self.display.audioPlayer.play()
+                if QtCore.QSettings().value(
+                    self.parent().generalSettingsSection + \
+                        u'/audio start paused',
+                    QtCore.QVariant(True)).toBool():
+                    self.audioPauseItem.setChecked(True)
+                    self.display.audioPlayer.pause()
+                else:
+                    self.display.audioPlayer.play()
                 self.setAudioItemsVisibility(True)
         row = 0
         text = []

=== modified file 'openlp/plugins/songs/forms/songimportform.py'
--- openlp/plugins/songs/forms/songimportform.py	2011-08-05 11:21:39 +0000
+++ openlp/plugins/songs/forms/songimportform.py	2011-09-12 20:09:26 +0000
@@ -686,7 +686,7 @@
     def performWizard(self):
         """
         Perform the actual import. This method pulls in the correct importer
-        class, and then runs the ``do_import`` method of the importer to do
+        class, and then runs the ``doImport`` method of the importer to do
         the actual importing.
         """
         source_format = self.formatComboBox.currentIndex()
@@ -759,8 +759,8 @@
             importer = self.plugin.importSongs(SongFormat.FoilPresenter,
                 filenames=self.getListOfFiles(self.foilPresenterFileListWidget)
             )
-        importer.do_import()
-        if importer.error_log:
+        importer.doImport()
+        if importer.errorLog:
             self.progressLabel.setText(translate(
                 'SongsPlugin.SongImportForm', 'Your song import failed.'))
         else:

=== modified file 'openlp/plugins/songs/lib/cclifileimport.py'
--- openlp/plugins/songs/lib/cclifileimport.py	2011-06-12 16:02:52 +0000
+++ openlp/plugins/songs/lib/cclifileimport.py	2011-09-12 20:09:26 +0000
@@ -55,13 +55,13 @@
         """
         SongImport.__init__(self, manager, **kwargs)
 
-    def do_import(self):
+    def doImport(self):
         """
         Import either a ``.usr`` or a ``.txt`` SongSelect file.
         """
         log.debug(u'Starting CCLI File Import')
-        self.import_wizard.progressBar.setMaximum(len(self.import_source))
-        for filename in self.import_source:
+        self.importWizard.progressBar.setMaximum(len(self.importSource))
+        for filename in self.importSource:
             filename = unicode(filename)
             log.debug(u'Importing CCLI File: %s', filename)
             lines = []
@@ -80,23 +80,23 @@
                 ext = os.path.splitext(filename)[1]
                 if ext.lower() == u'.usr':
                     log.info(u'SongSelect .usr format file found: %s', filename)
-                    if not self.do_import_usr_file(lines):
-                        self.log_error(filename)
+                    if not self.doImportUsrFile(lines):
+                        self.logError(filename)
                 elif ext.lower() == u'.txt':
                     log.info(u'SongSelect .txt format file found: %s', filename)
-                    if not self.do_import_txt_file(lines):
-                        self.log_error(filename)
+                    if not self.doImportTxtFile(lines):
+                        self.logError(filename)
                 else:
-                    self.log_error(filename,
+                    self.logError(filename,
                         translate('SongsPlugin.CCLIFileImport',
                         'The file does not have a valid extension.'))
                     log.info(u'Extension %s is not valid', filename)
-            if self.stop_import_flag:
+            if self.stopImportFlag:
                 return
 
-    def do_import_usr_file(self, textList):
+    def doImportUsrFile(self, textList):
         """
-        The :func:`do_import_usr_file` method provides OpenLP with the ability
+        The :func:`doImport_usr_file` method provides OpenLP with the ability
         to import CCLI SongSelect songs in *USR* file format.
 
         ``textList``
@@ -165,7 +165,7 @@
             elif line.startswith(u'Themes='):
                 song_topics = line[7:].strip()
             elif line.startswith(u'[S A'):
-                self.ccli_number = line[4:-3].strip()
+                self.ccliNumber = line[4:-3].strip()
             elif line.startswith(u'Fields='):
                 # Fields contain single line indicating verse, chorus, etc,
                 # /t delimited, same as with words field. store seperately
@@ -204,7 +204,7 @@
                     verse_type = VerseType.Tags[VerseType.Other]
                     verse_text = verse_lines[1]
             if len(verse_text) > 0:
-                self.add_verse(verse_text, verse_type)
+                self.addVerse(verse_text, verse_type)
             check_first_verse_line = False
         # Handle multiple authors
         author_list = song_author.split(u'/')
@@ -213,15 +213,15 @@
         for author in author_list:
             separated = author.split(u',')
             if len(separated) > 1:
-                self.add_author(u' '.join(reversed(separated)))
+                self.addAuthor(u' '.join(reversed(separated)))
             else:
-                self.add_author(author)
+                self.addAuthor(author)
         self.topics = [topic.strip() for topic in song_topics.split(u'/t')]
         return self.finish()
 
-    def do_import_txt_file(self, textList):
+    def doImportTxtFile(self, textList):
         """
-        The :func:`do_import_txt_file` method provides OpenLP with the ability
+        The :func:`doImport_txt_file` method provides OpenLP with the ability
         to import CCLI SongSelect songs in *TXT* file format.
 
         ``textList``
@@ -264,7 +264,7 @@
                     continue
                 elif verse_start:
                     if verse_text:
-                        self.add_verse(verse_text, verse_type)
+                        self.addVerse(verse_text, verse_type)
                         verse_text = u''
                         verse_start = False
             else:
@@ -278,7 +278,7 @@
                     if clean_line.startswith(u'CCLI'):
                         line_number += 1
                         ccli_parts = clean_line.split(' ')
-                        self.ccli_number = ccli_parts[len(ccli_parts) - 1]
+                        self.ccliNumber = ccli_parts[len(ccli_parts) - 1]
                     elif not verse_start:
                         # We have the verse descriptor
                         verse_desc_parts = clean_line.split(u' ')
@@ -333,5 +333,5 @@
         if len(author_list) < 2:
             author_list = song_author.split(u'|')
         # Clean spaces before and after author names.
-        [self.add_author(author_name.strip()) for author_name in author_list]
+        [self.addAuthor(author_name.strip()) for author_name in author_list]
         return self.finish()

=== modified file 'openlp/plugins/songs/lib/easislidesimport.py'
--- openlp/plugins/songs/lib/easislidesimport.py	2011-07-07 18:03:12 +0000
+++ openlp/plugins/songs/lib/easislidesimport.py	2011-09-12 20:09:26 +0000
@@ -49,50 +49,50 @@
         SongImport.__init__(self, manager, **kwargs)
         self.commit = True
 
-    def do_import(self):
+    def doImport(self):
         """
-        Import either each of the files in self.import_sources - each element of
+        Import either each of the files in self.importSources - each element of
         which can be either a single opensong file, or a zipfile containing
         multiple opensong files. If `self.commit` is set False, the
         import will not be committed to the database (useful for test scripts).
         """
-        log.info(u'Importing EasiSlides XML file %s', self.import_source)
+        log.info(u'Importing EasiSlides XML file %s', self.importSource)
         parser = etree.XMLParser(remove_blank_text=True)
-        parsed_file = etree.parse(self.import_source, parser)
+        parsed_file = etree.parse(self.importSource, parser)
         xml = unicode(etree.tostring(parsed_file))
         song_xml = objectify.fromstring(xml)
-        self.import_wizard.progressBar.setMaximum(len(song_xml.Item))
+        self.importWizard.progressBar.setMaximum(len(song_xml.Item))
         for song in song_xml.Item:
-            if self.stop_import_flag:
+            if self.stopImportFlag:
                 return
-            self._parse_song(song)
+            self._parseSong(song)
 
-    def _parse_song(self, song):
+    def _parseSong(self, song):
         self._success = True
-        self._add_unicode_attribute(u'title', song.Title1, True)
+        self._addUnicodeAttribute(u'title', song.Title1, True)
         if hasattr(song, u'Title2'):
-            self._add_unicode_attribute(u'alternate_title', song.Title2)
+            self._addUnicodeAttribute(u'alternateTitle', song.Title2)
         if hasattr(song, u'SongNumber'):
-            self._add_unicode_attribute(u'song_number', song.SongNumber)
-        if self.song_number == u'0':
-            self.song_number = u''
-        self._add_authors(song)
+            self._addUnicodeAttribute(u'songNumber', song.SongNumber)
+        if self.songNumber == u'0':
+            self.songNumber = u''
+        self._addAuthors(song)
         if hasattr(song, u'Copyright'):
-            self._add_copyright(song.Copyright)
+            self._addCopyright(song.Copyright)
         if hasattr(song, u'LicenceAdmin1'):
-            self._add_copyright(song.LicenceAdmin1)
+            self._addCopyright(song.LicenceAdmin1)
         if hasattr(song, u'LicenceAdmin2'):
-            self._add_copyright(song.LicenceAdmin2)
+            self._addCopyright(song.LicenceAdmin2)
         if hasattr(song, u'BookReference'):
-            self._add_unicode_attribute(u'song_book_name', song.BookReference)
-        self._parse_and_add_lyrics(song)
+            self._addUnicodeAttribute(u'songBookName', song.BookReference)
+        self._parseAndAddLyrics(song)
         if self._success:
             if not self.finish():
-                self.log_error(song.Title1 if song.Title1 else u'')
+                self.logError(song.Title1 if song.Title1 else u'')
         else:
-            self.set_defaults()
+            self.setDefaults()
 
-    def _add_unicode_attribute(self, self_attribute, import_attribute,
+    def _addUnicodeAttribute(self, self_attribute, import_attribute,
         mandatory=False):
         """
         Add imported values to the song model converting them to unicode at the
@@ -119,7 +119,7 @@
             if mandatory:
                 self._success = False
 
-    def _add_authors(self, song):
+    def _addAuthors(self, song):
         try:
             authors = unicode(song.Writer).split(u',')
             self.authors = \
@@ -130,7 +130,7 @@
         except AttributeError:
             pass
 
-    def _add_copyright(self, element):
+    def _addCopyright(self, element):
         """
         Add a piece of copyright to the total copyright information for the
         song.
@@ -139,14 +139,14 @@
             The imported variable to get the data from.
         """
         try:
-            self.add_copyright(unicode(element).strip())
+            self.addCopyright(unicode(element).strip())
         except UnicodeDecodeError:
             log.exception(u'Unicode error on decoding copyright: %s' % element)
             self._success = False
         except AttributeError:
             pass
 
-    def _parse_and_add_lyrics(self, song):
+    def _parseAndAddLyrics(self, song):
         try:
             lyrics = unicode(song.Contents).strip()
         except UnicodeDecodeError:
@@ -295,7 +295,7 @@
                 else:
                     continue
                 if tag in versetags:
-                    self.verse_order_list.append(tag)
+                    self.verseOrderList.append(tag)
                 else:
                     log.info(u'Got order item %s, which is not in versetags,'
                         u'dropping item from presentation order', tag)

=== modified file 'openlp/plugins/songs/lib/ewimport.py'
--- openlp/plugins/songs/lib/ewimport.py	2011-07-07 18:04:26 +0000
+++ openlp/plugins/songs/lib/ewimport.py	2011-09-12 20:09:26 +0000
@@ -49,15 +49,15 @@
     control = False
     clear_text = []
     control_word = []
-    
-    # workaround for \tx bug: remove one pair of curly braces 
+
+    # workaround for \tx bug: remove one pair of curly braces
     # if \tx is encountered
     match = RTF_STRIPPING_REGEX.search(blob)
     if match:
         # start and end indices of match are curly braces - filter them out
-        blob = ''.join([blob[i] for i in xrange(len(blob)) 
+        blob = ''.join([blob[i] for i in xrange(len(blob))
             if i != match.start() and i !=match.end()])
-    
+
     for c in blob:
         if control:
             # for delimiters, set control to False
@@ -155,24 +155,24 @@
     def __init__(self, manager, **kwargs):
         SongImport.__init__(self, manager, **kwargs)
 
-    def do_import(self):
+    def doImport(self):
         # Open the DB and MB files if they exist
-        import_source_mb = self.import_source.replace('.DB', '.MB')
-        if not os.path.isfile(self.import_source):
+        import_source_mb = self.importSource.replace('.DB', '.MB')
+        if not os.path.isfile(self.importSource):
             return
         if not os.path.isfile(import_source_mb):
             return
-        db_size = os.path.getsize(self.import_source)
+        db_size = os.path.getsize(self.importSource)
         if db_size < 0x800:
             return
-        db_file = open(self.import_source, 'rb')
-        self.memo_file = open(import_source_mb, 'rb')
+        db_file = open(self.importSource, 'rb')
+        self.memoFile = open(import_source_mb, 'rb')
         # Don't accept files that are clearly not paradox files
         record_size, header_size, block_size, first_block, num_fields \
             = struct.unpack('<hhxb8xh17xh', db_file.read(35))
         if header_size != 0x800 or block_size < 1 or block_size > 4:
             db_file.close()
-            self.memo_file.close()
+            self.memoFile.close()
             return
         # Take a stab at how text is encoded
         self.encoding = u'cp1252'
@@ -204,7 +204,7 @@
         # There does not appear to be a _reliable_ way of getting the number
         # of songs/records, so let's use file blocks for measuring progress.
         total_blocks = (db_size - header_size) / (block_size * 1024)
-        self.import_wizard.progressBar.setMaximum(total_blocks)
+        self.importWizard.progressBar.setMaximum(total_blocks)
         # Read the field description information
         db_file.seek(120)
         field_info = db_file.read(num_fields * 2)
@@ -218,16 +218,16 @@
                 field_info, i * 2)
             field_descs.append(FieldDescEntry(field_name, field_type,
                 field_size))
-        self.set_record_struct(field_descs)
+        self.setRecordStruct(field_descs)
         # Pick out the field description indexes we will need
         try:
             success = True
-            fi_title = self.find_field(u'Title')
-            fi_author = self.find_field(u'Author')
-            fi_copy = self.find_field(u'Copyright')
-            fi_admin = self.find_field(u'Administrator')
-            fi_words = self.find_field(u'Words')
-            fi_ccli = self.find_field(u'Song Number')
+            fi_title = self.findField(u'Title')
+            fi_author = self.findField(u'Author')
+            fi_copy = self.findField(u'Copyright')
+            fi_admin = self.findField(u'Administrator')
+            fi_words = self.findField(u'Words')
+            fi_ccli = self.findField(u'Song Number')
         except IndexError:
             # This is the wrong table
             success = False
@@ -239,18 +239,18 @@
             rec_count = (rec_count + record_size) / record_size
             # Loop through each record within the current block
             for i in range(rec_count):
-                if self.stop_import_flag:
+                if self.stopImportFlag:
                     break
                 raw_record = db_file.read(record_size)
                 self.fields = self.record_struct.unpack(raw_record)
-                self.set_defaults()
-                self.title = self.get_field(fi_title)
+                self.setDefaults()
+                self.title = self.getField(fi_title)
                 # Get remaining fields.
-                copy = self.get_field(fi_copy)
-                admin = self.get_field(fi_admin)
-                ccli = self.get_field(fi_ccli)
-                authors = self.get_field(fi_author)
-                words = self.get_field(fi_words)
+                copy = self.getField(fi_copy)
+                admin = self.getField(fi_admin)
+                ccli = self.getField(fi_ccli)
+                authors = self.getField(fi_author)
+                words = self.getField(fi_words)
                 # Set the SongImport object members.
                 if copy:
                     self.copyright = copy
@@ -261,7 +261,7 @@
                         unicode(translate('SongsPlugin.EasyWorshipSongImport',
                             'Administered by %s')) % admin
                 if ccli:
-                    self.ccli_number = ccli
+                    self.ccliNumber = ccli
                 if authors:
                     # Split up the authors
                     author_list = authors.split(u'/')
@@ -270,7 +270,7 @@
                     if len(author_list) < 2:
                         author_list = authors.split(u',')
                     for author_name in author_list:
-                        self.add_author(author_name.strip())
+                        self.addAuthor(author_name.strip())
                 if words:
                     # Format the lyrics
                     words = strip_rtf(words, self.encoding)
@@ -281,9 +281,9 @@
                             continue
                         verse_split = verse.split(u'\n', 1)
                         first_line_is_tag = False
-                        # EW tags: verse, chorus, pre-chorus, bridge, tag, 
+                        # EW tags: verse, chorus, pre-chorus, bridge, tag,
                         # intro, ending, slide
-                        for type in VerseType.Names+[u'tag', u'slide']: 
+                        for type in VerseType.Names+[u'tag', u'slide']:
                             type = type.lower()
                             ew_tag = verse_split[0].strip().lower()
                             if ew_tag.startswith(type):
@@ -293,7 +293,7 @@
                                 first_line_is_tag = True
                                 number_found = False
                                 # check if tag is followed by number and/or note
-                                if len(ew_tag) > len(type): 
+                                if len(ew_tag) > len(type):
                                     match = NUMBER_REGEX.search(ew_tag)
                                     if match:
                                         number = match.group()
@@ -305,23 +305,24 @@
                                 if not number_found:
                                     verse_type += u'1'
                                 break
-                        self.add_verse(
-                            verse_split[-1].strip() if first_line_is_tag else verse, 
+                        self.addVerse(
+                            verse_split[-1].strip() \
+                                if first_line_is_tag else verse,
                             verse_type)
                 if len(self.comments) > 5:
                     self.comments += unicode(
                         translate('SongsPlugin.EasyWorshipSongImport',
                         '\n[above are Song Tags with notes imported from \
                         EasyWorship]'))
-                if self.stop_import_flag:
+                if self.stopImportFlag:
                     break
                 if not self.finish():
-                    self.log_error(self.import_source)
+                    self.logError(self.importSource)
         db_file.close()
-        self.memo_file.close()
+        self.memoFile.close()
 
     def find_field(self, field_name):
-        return [i for i, x in enumerate(self.field_descs)
+        return [i for i, x in enumerate(self.fieldDescs)
             if x.name == field_name][0]
 
     def set_record_struct(self, field_descs):
@@ -351,12 +352,12 @@
                 fsl.append('Q')
             else:
                 fsl.append('%ds' % field_desc.size)
-        self.record_struct = struct.Struct(''.join(fsl))
-        self.field_descs = field_descs
+        self.recordStruct = struct.Struct(''.join(fsl))
+        self.fieldDescs = field_descs
 
     def get_field(self, field_desc_index):
         field = self.fields[field_desc_index]
-        field_desc = self.field_descs[field_desc_index]
+        field_desc = self.fieldDescs[field_desc_index]
         # Return None in case of 'blank' entries
         if isinstance(field, str):
             if len(field.rstrip('\0')) == 0:
@@ -382,18 +383,18 @@
                 struct.unpack_from('<II', field, len(field)-10)
             sub_block = block_start & 0xff
             block_start &= ~0xff
-            self.memo_file.seek(block_start)
-            memo_block_type, = struct.unpack('b', self.memo_file.read(1))
+            self.memoFile.seek(block_start)
+            memo_block_type, = struct.unpack('b', self.memoFile.read(1))
             if memo_block_type == 2:
-                self.memo_file.seek(8, os.SEEK_CUR)
+                self.memoFile.seek(8, os.SEEK_CUR)
             elif memo_block_type == 3:
                 if sub_block > 63:
                     return u''
-                self.memo_file.seek(11 + (5 * sub_block), os.SEEK_CUR)
-                sub_block_start, = struct.unpack('B', self.memo_file.read(1))
-                self.memo_file.seek(block_start + (sub_block_start * 16))
+                self.memoFile.seek(11 + (5 * sub_block), os.SEEK_CUR)
+                sub_block_start, = struct.unpack('B', self.memoFile.read(1))
+                self.memoFile.seek(block_start + (sub_block_start * 16))
             else:
                 return u''
-            return self.memo_file.read(blob_size)
+            return self.memoFile.read(blob_size)
         else:
             return 0

=== modified file 'openlp/plugins/songs/lib/foilpresenterimport.py'
--- openlp/plugins/songs/lib/foilpresenterimport.py	2011-06-12 16:02:52 +0000
+++ openlp/plugins/songs/lib/foilpresenterimport.py	2011-09-12 20:09:26 +0000
@@ -115,23 +115,23 @@
         SongImport.__init__(self, manager, **kwargs)
         self.FoilPresenter = FoilPresenter(self.manager)
 
-    def do_import(self):
+    def doImport(self):
         """
         Imports the songs.
         """
-        self.import_wizard.progressBar.setMaximum(len(self.import_source))
+        self.importWizard.progressBar.setMaximum(len(self.importSource))
         parser = etree.XMLParser(remove_blank_text=True)
-        for file_path in self.import_source:
-            if self.stop_import_flag:
+        for file_path in self.importSource:
+            if self.stopImportFlag:
                 return
-            self.import_wizard.incrementProgressBar(
+            self.importWizard.incrementProgressBar(
                 WizardStrings.ImportingType % os.path.basename(file_path))
             try:
                 parsed_file = etree.parse(file_path, parser)
                 xml = unicode(etree.tostring(parsed_file))
                 self.FoilPresenter.xml_to_song(xml)
             except etree.XMLSyntaxError:
-                self.log_error(file_path, SongStrings.XMLSyntaxError)
+                self.logError(file_path, SongStrings.XMLSyntaxError)
                 log.exception(u'XML syntax error in file %s' % file_path)
 
 

=== modified file 'openlp/plugins/songs/lib/mediaitem.py'
--- openlp/plugins/songs/lib/mediaitem.py	2011-09-06 17:53:43 +0000
+++ openlp/plugins/songs/lib/mediaitem.py	2011-09-12 20:09:26 +0000
@@ -69,11 +69,11 @@
     def __init__(self, parent, plugin, icon):
         self.IconPath = u'songs/song'
         MediaManagerItem.__init__(self, parent, plugin, icon)
-        self.edit_song_form = EditSongForm(self, self.plugin.formparent,
+        self.editSongForm = EditSongForm(self, self.plugin.formparent,
             self.plugin.manager)
         self.openLyrics = OpenLyrics(self.plugin.manager)
         self.singleServiceItem = False
-        self.song_maintenance_form = SongMaintenanceForm(
+        self.songMaintenanceForm = SongMaintenanceForm(
             self.plugin.manager, self)
         # Holds information about whether the edit is remotly triggered and
         # which Song is required.
@@ -316,25 +316,26 @@
                 self.onClearTextButtonClick()
 
     def onImportClick(self):
-        if not hasattr(self, u'import_wizard'):
-            self.import_wizard = SongImportForm(self, self.plugin)
-        if self.import_wizard.exec_() == QtGui.QDialog.Accepted:
+        if not hasattr(self, u'importWizard'):
+            self.importWizard = SongImportForm(self, self.plugin)
+        if self.importWizard.exec_() == QtGui.QDialog.Accepted:
             Receiver.send_message(u'songs_load_list')
 
     def onExportClick(self):
-        export_wizard = SongExportForm(self, self.plugin)
-        export_wizard.exec_()
+        if not hasattr(self, u'exportWizard'):
+            self.exportWizard = SongExportForm(self, self.plugin)
+        self.exportWizard.exec_()
 
     def onNewClick(self):
         log.debug(u'onNewClick')
-        self.edit_song_form.newSong()
-        self.edit_song_form.exec_()
+        self.editSongForm.newSong()
+        self.editSongForm.exec_()
         self.onClearTextButtonClick()
         self.onSelectionChange()
         self.autoSelectId = -1
 
     def onSongMaintenanceClick(self):
-        self.song_maintenance_form.exec_()
+        self.songMaintenanceForm.exec_()
 
     def onRemoteEditClear(self):
         log.debug(u'onRemoteEditClear')
@@ -354,8 +355,8 @@
         if valid:
             self.remoteSong = song_id
             self.remoteTriggered = remote_type
-            self.edit_song_form.loadSong(song_id, remote_type == u'P')
-            self.edit_song_form.exec_()
+            self.editSongForm.loadSong(song_id, remote_type == u'P')
+            self.editSongForm.exec_()
             self.autoSelectId = -1
             self.onSongListLoad()
 
@@ -367,8 +368,8 @@
         if check_item_selected(self.listView, UiStrings().SelectEdit):
             self.editItem = self.listView.currentItem()
             item_id = (self.editItem.data(QtCore.Qt.UserRole)).toInt()[0]
-            self.edit_song_form.loadSong(item_id, False)
-            self.edit_song_form.exec_()
+            self.editSongForm.loadSong(item_id, False)
+            self.editSongForm.exec_()
             self.autoSelectId = -1
             self.onSongListLoad()
         self.editItem = None
@@ -390,6 +391,18 @@
                 return
             for item in items:
                 item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
+                media_files = self.plugin.manager.get_all_objects(MediaFile,
+                    MediaFile.song_id == item_id)
+                for media_file in media_files:
+                    try:
+                        os.remove(media_file.file_name)
+                    except:
+                        log.exception('Could not remove file: %s', audio)
+                try:
+                    os.rmdir(os.path.join(AppLocation.get_section_data_path(
+                        self.plugin.name), 'audio', str(item_id)))
+                except OSError:
+                    log.exception(u'Could not remove directory: %s', save_path)
                 self.plugin.manager.delete_object(Song, item_id)
             self.onSearchTextButtonClick()
 

=== modified file 'openlp/plugins/songs/lib/olp1import.py'
--- openlp/plugins/songs/lib/olp1import.py	2011-08-05 11:21:39 +0000
+++ openlp/plugins/songs/lib/olp1import.py	2011-09-12 20:09:26 +0000
@@ -32,6 +32,8 @@
 import logging
 from chardet.universaldetector import UniversalDetector
 import sqlite
+import sys
+import os
 
 from openlp.core.lib import translate
 from openlp.plugins.songs.lib import retrieve_windows_encoding
@@ -44,7 +46,7 @@
     The :class:`OpenLP1SongImport` class provides OpenLP with the ability to
     import song databases from installations of openlp.org 1.x.
     """
-    last_encoding = u'windows-1252'
+    lastEncoding = u'windows-1252'
 
     def __init__(self, manager, **kwargs):
         """
@@ -57,23 +59,23 @@
             The database providing the data to import.
         """
         SongImport.__init__(self, manager, **kwargs)
-        self.available_themes = \
+        self.availableThemes = \
             kwargs[u'plugin'].formparent.themeManagerContents.getThemes()
 
-    def do_import(self):
+    def doImport(self):
         """
         Run the import for an openlp.org 1.x song database.
         """
-        if not self.import_source.endswith(u'.olp'):
-            self.log_error(self.import_source,
+        if not self.importSource.endswith(u'.olp'):
+            self.logError(self.importSource,
                 translate('SongsPlugin.OpenLP1SongImport',
                 'Not a valid openlp.org 1.x song database.'))
             return
-        encoding = self.get_encoding()
+        encoding = self.getEncoding()
         if not encoding:
             return
         # Connect to the database.
-        connection = sqlite.connect(self.import_source, mode=0444,
+        connection = sqlite.connect(self.importSource, mode=0444,
             encoding=(encoding, 'replace'))
         cursor = connection.cursor()
         # Determine if we're using a new or an old DB.
@@ -94,64 +96,66 @@
         cursor.execute(u'SELECT settingsid, settingsname FROM settings')
         themes = {}
         for theme_id, theme_name in cursor.fetchall():
-            if theme_name in self.available_themes:
+            if theme_name in self.availableThemes:
                 themes[theme_id] = theme_name
         # Import the songs.
         cursor.execute(u'-- types int, unicode, unicode, unicode, int')
         cursor.execute(u'SELECT songid, songtitle, lyrics || \'\' AS lyrics, '
             u'copyrightinfo, settingsid FROM songs')
         songs = cursor.fetchall()
-        self.import_wizard.progressBar.setMaximum(len(songs))
+        self.importWizard.progressBar.setMaximum(len(songs))
         for song in songs:
-            self.set_defaults()
-            if self.stop_import_flag:
+            self.setDefaults()
+            if self.stopImportFlag:
                 break
             song_id = song[0]
             self.title = song[1]
             lyrics = song[2].replace(u'\r\n', u'\n')
-            self.add_copyright(song[3])
+            self.addCopyright(song[3])
             if themes.has_key(song[4]):
-                self.theme_name = themes[song[4]]
+                self.themeName = themes[song[4]]
             verses = lyrics.split(u'\n\n')
             for verse in verses:
                 if verse.strip():
-                    self.add_verse(verse.strip())
+                    self.addVerse(verse.strip())
             cursor.execute(u'-- types int')
             cursor.execute(u'SELECT authorid FROM songauthors '
                 u'WHERE songid = %s' % song_id)
             author_ids = cursor.fetchall()
             for author_id in author_ids:
-                if self.stop_import_flag:
+                if self.stopImportFlag:
                     break
                 for author in authors:
                     if author[0] == author_id[0]:
-                        self.parse_author(author[1])
+                        self.parseAuthor(author[1])
                         break
-            if self.stop_import_flag:
+            if self.stopImportFlag:
                 break
             if new_db:
-                cursor.execute(u'-- types int')
-                cursor.execute(u'SELECT trackid FROM songtracks '
+                cursor.execute(u'-- types int, int')
+                cursor.execute(u'SELECT trackid, listindex '
+                    u'FROM songtracks '
                     u'WHERE songid = %s ORDER BY listindex' % song_id)
                 track_ids = cursor.fetchall()
-                for track_id in track_ids:
-                    if self.stop_import_flag:
+                for track_id, listindex in track_ids:
+                    if self.stopImportFlag:
                         break
                     for track in tracks:
-                        if track[0] == track_id[0]:
-                            self.add_media_file(track[1])
+                        if track[0] == track_id:
+                            media_file = self.expandMediaFile(track[1])
+                            self.addMediaFile(media_file, listindex)
                             break
-            if self.stop_import_flag:
+            if self.stopImportFlag:
                 break
             if not self.finish():
-                self.log_error(self.import_source)
+                self.logError(self.importSource)
 
-    def get_encoding(self):
+    def getEncoding(self):
         """
         Detect character encoding of an openlp.org 1.x song database.
         """
         # Connect to the database.
-        connection = sqlite.connect(self.import_source, mode=0444)
+        connection = sqlite.connect(self.importSource, mode=0444)
         cursor = connection.cursor()
 
         detector = UniversalDetector()
@@ -186,3 +190,22 @@
                     return detector.result[u'encoding']
         detector.close()
         return retrieve_windows_encoding(detector.result[u'encoding'])
+
+    def expandMediaFile(self, filename):
+        """
+        When you're on Windows, this function expands the file name to include
+        the path to OpenLP's application data directory. If you are not on
+        Windows, it returns the original file name.
+
+        ``filename``
+            The filename to expand.
+        """
+        if sys.platform != u'win32' and \
+            not os.environ.get(u'ALLUSERSPROFILE') and \
+            not os.environ.get(u'APPDATA'):
+            return filename
+        common_app_data = os.path.join(os.environ[u'ALLUSERSPROFILE'],
+            os.path.split(os.environ[u'APPDATA'])[1])
+        if not common_app_data:
+            return filename
+        return os.path.join(common_app_data, u'openlp.org', 'Audio', filename)

=== modified file 'openlp/plugins/songs/lib/olpimport.py'
--- openlp/plugins/songs/lib/olpimport.py	2011-06-12 16:02:52 +0000
+++ openlp/plugins/songs/lib/olpimport.py	2011-09-12 20:09:26 +0000
@@ -95,22 +95,22 @@
             The database providing the data to import.
         """
         SongImport.__init__(self, manager, **kwargs)
-        self.source_session = None
+        self.sourceSession = None
 
-    def do_import(self):
+    def doImport(self):
         """
         Run the import for an OpenLP version 2 song database.
         """
-        if not self.import_source.endswith(u'.sqlite'):
-            self.log_error(self.import_source,
+        if not self.importSource.endswith(u'.sqlite'):
+            self.logError(self.importSource,
                 translate('SongsPlugin.OpenLPSongImport',
                 'Not a valid OpenLP 2.0 song database.'))
             return
-        self.import_source = u'sqlite:///%s' % self.import_source
-        engine = create_engine(self.import_source)
+        self.importSource = u'sqlite:///%s' % self.importSource
+        engine = create_engine(self.importSource)
         source_meta = MetaData()
         source_meta.reflect(engine)
-        self.source_session = scoped_session(sessionmaker(bind=engine))
+        self.sourceSession = scoped_session(sessionmaker(bind=engine))
         if u'media_files' in source_meta.tables.keys():
             has_media_files = True
         else:
@@ -156,9 +156,9 @@
         except UnmappedClassError:
             mapper(OldTopic, source_topics_table)
 
-        source_songs = self.source_session.query(OldSong).all()
-        if self.import_wizard:
-            self.import_wizard.progressBar.setMaximum(len(source_songs))
+        source_songs = self.sourceSession.query(OldSong).all()
+        if self.importWizard:
+            self.importWizard.progressBar.setMaximum(len(source_songs))
         for song in source_songs:
             new_song = Song()
             new_song.title = song.title
@@ -201,22 +201,22 @@
                     if existing_topic is None:
                         existing_topic = Topic.populate(name=topic.name)
                     new_song.topics.append(existing_topic)
-#            if has_media_files:
-#                if song.media_files:
-#                    for media_file in song.media_files:
-#                        existing_media_file = \
-#                            self.manager.get_object_filtered(MediaFile,
-#                                MediaFile.file_name == media_file.file_name)
-#                        if existing_media_file:
-#                            new_song.media_files.append(existing_media_file)
-#                        else:
-#                            new_song.media_files.append(MediaFile.populate(
-#                                file_name=media_file.file_name))
+            if has_media_files:
+                if song.media_files:
+                    for media_file in song.media_files:
+                        existing_media_file = \
+                            self.manager.get_object_filtered(MediaFile,
+                                MediaFile.file_name == media_file.file_name)
+                        if existing_media_file:
+                            new_song.media_files.append(existing_media_file)
+                        else:
+                            new_song.media_files.append(MediaFile.populate(
+                                file_name=media_file.file_name))
             clean_song(self.manager, new_song)
             self.manager.save_object(new_song)
-            if self.import_wizard:
-                self.import_wizard.incrementProgressBar(
+            if self.importWizard:
+                self.importWizard.incrementProgressBar(
                     WizardStrings.ImportingType % new_song.title)
-            if self.stop_import_flag:
+            if self.stopImportFlag:
                 break
         engine.dispose()

=== modified file 'openlp/plugins/songs/lib/oooimport.py'
--- openlp/plugins/songs/lib/oooimport.py	2011-06-23 22:26:36 +0000
+++ openlp/plugins/songs/lib/oooimport.py	2011-09-12 20:09:26 +0000
@@ -59,58 +59,58 @@
         """
         SongImport.__init__(self, manager, **kwargs)
         self.document = None
-        self.process_started = False
+        self.processStarted = False
 
-    def do_import(self):
-        if not isinstance(self.import_source, list):
+    def doImport(self):
+        if not isinstance(self.importSource, list):
             return
         try:
             self.start_ooo()
         except NoConnectException as exc:
-            self.log_error(
-                self.import_source[0],
+            self.logError(
+                self.importSource[0],
                 translate('SongsPlugin.SongImport',
                 'Cannot access OpenOffice or LibreOffice'))
             log.error(exc)
             return
-        self.import_wizard.progressBar.setMaximum(len(self.import_source))
-        for filename in self.import_source:
-            if self.stop_import_flag:
+        self.importWizard.progressBar.setMaximum(len(self.importSource))
+        for filename in self.importSource:
+            if self.stopImportFlag:
                 break
             filename = unicode(filename)
             if os.path.isfile(filename):
-                self.open_ooo_file(filename)
+                self.openOooFile(filename)
                 if self.document:
-                    self.process_ooo_document()
-                    self.close_ooo_file()
+                    self.processOooDocument()
+                    self.closeOooFile()
                 else:
-                    self.log_error(self.filepath,
+                    self.logError(self.filepath,
                         translate('SongsPlugin.SongImport',
                         'Unable to open file'))
             else:
-                self.log_error(self.filepath,
+                self.logError(self.filepath,
                     translate('SongsPlugin.SongImport', 'File not found'))
-        self.close_ooo()
+        self.closeOoo()
 
-    def process_ooo_document(self):
+    def processOooDocument(self):
         """
         Handle the import process for OpenOffice files. This method facilitates
         allowing subclasses to handle specific types of OpenOffice files.
         """
         if self.document.supportsService(
             "com.sun.star.presentation.PresentationDocument"):
-            self.process_pres()
+            self.processPres()
         if self.document.supportsService("com.sun.star.text.TextDocument"):
-            self.process_doc()
+            self.processDoc()
 
-    def start_ooo(self):
+    def startOoo(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.ooo_manager.createInstance(
+            self.startOooProcess()
+            self.desktop = self.oooManager.createInstance(
                 u'com.sun.star.frame.Desktop')
         else:
             context = uno.getComponentContext()
@@ -123,7 +123,7 @@
                     uno_instance = get_uno_instance(resolver)
                 except NoConnectException:
                     log.exception("Failed to resolve uno connection")
-                    self.start_ooo_process()
+                    self.startOooProcess()
                     loop += 1
                 else:
                     manager = uno_instance.ServiceManager
@@ -132,22 +132,22 @@
                     return
             raise
 
-    def start_ooo_process(self):
+    def startOooProcess(self):
         try:
             if os.name == u'nt':
-                self.ooo_manager = Dispatch(u'com.sun.star.ServiceManager')
-                self.ooo_manager._FlagAsMethod(u'Bridge_GetStruct')
-                self.ooo_manager._FlagAsMethod(u'Bridge_GetValueObject')
+                self.oooManager = Dispatch(u'com.sun.star.ServiceManager')
+                self.oooManager._FlagAsMethod(u'Bridge_GetStruct')
+                self.oooManager._FlagAsMethod(u'Bridge_GetValueObject')
             else:
                 cmd = get_uno_command()
                 process = QtCore.QProcess()
                 process.startDetached(cmd)
                 process.waitForStarted()
-            self.process_started = True
+            self.processStarted = True
         except:
             log.exception("start_ooo_process failed")
 
-    def open_ooo_file(self, filepath):
+    def openOooFile(self, filepath):
         """
         Open the passed file in OpenOffice.org Impress
         """
@@ -166,29 +166,29 @@
             if not self.document.supportsService(
                 "com.sun.star.presentation.PresentationDocument") and not \
                 self.document.supportsService("com.sun.star.text.TextDocument"):
-                self.close_ooo_file()
+                self.closeOooFile()
             else:
-                self.import_wizard.incrementProgressBar(
+                self.importWizard.incrementProgressBar(
                     u'Processing file ' + filepath, 0)
         except AttributeError:
             log.exception("open_ooo_file failed: %s", url)
         return
 
-    def close_ooo_file(self):
+    def closeOooFile(self):
         """
         Close file.
         """
         self.document.close(True)
         self.document = None
 
-    def close_ooo(self):
+    def closeOoo(self):
         """
         Close OOo. But only if we started it and not on windows
         """
-        if self.process_started:
+        if self.processStarted:
             self.desktop.terminate()
 
-    def process_pres(self):
+    def processPres(self):
         """
         Process the file
         """
@@ -196,8 +196,8 @@
         slides = doc.getDrawPages()
         text = u''
         for slide_no in range(slides.getCount()):
-            if self.stop_import_flag:
-                self.import_wizard.incrementProgressBar(u'Import cancelled', 0)
+            if self.stopImportFlag:
+                self.importWizard.incrementProgressBar(u'Import cancelled', 0)
                 return
             slide = slides.getByIndex(slide_no)
             slidetext = u''
@@ -209,10 +209,10 @@
             if slidetext.strip() == u'':
                 slidetext = u'\f'
             text += slidetext
-        self.process_songs_text(text)
+        self.processSongsText(text)
         return
 
-    def process_doc(self):
+    def processDoc(self):
         """
         Process the doc file, a paragraph at a time
         """
@@ -231,16 +231,16 @@
                     if textportion.BreakType in (PAGE_AFTER, PAGE_BOTH):
                         paratext += u'\f'
             text += paratext + u'\n'
-        self.process_songs_text(text)
+        self.processSongsText(text)
 
-    def process_songs_text(self, text):
-        songtexts = self.tidy_text(text).split(u'\f')
-        self.set_defaults()
+    def processSongsText(self, text):
+        songtexts = self.tidyText(text).split(u'\f')
+        self.setDefaults()
         for songtext in songtexts:
             if songtext.strip():
-                self.process_song_text(songtext.strip())
-                if self.check_complete():
+                self.processSongText(songtext.strip())
+                if self.checkComplete():
                     self.finish()
-                    self.set_defaults()
-        if self.check_complete():
+                    self.setDefaults()
+        if self.checkComplete():
             self.finish()

=== modified file 'openlp/plugins/songs/lib/openlyricsimport.py'
--- openlp/plugins/songs/lib/openlyricsimport.py	2011-06-12 16:02:52 +0000
+++ openlp/plugins/songs/lib/openlyricsimport.py	2011-09-12 20:09:26 +0000
@@ -53,16 +53,16 @@
         SongImport.__init__(self, manager, **kwargs)
         self.openLyrics = OpenLyrics(self.manager)
 
-    def do_import(self):
+    def doImport(self):
         """
         Imports the songs.
         """
-        self.import_wizard.progressBar.setMaximum(len(self.import_source))
+        self.importWizard.progressBar.setMaximum(len(self.importSource))
         parser = etree.XMLParser(remove_blank_text=True)
-        for file_path in self.import_source:
-            if self.stop_import_flag:
+        for file_path in self.importSource:
+            if self.stopImportFlag:
                 return
-            self.import_wizard.incrementProgressBar(
+            self.importWizard.incrementProgressBar(
                 WizardStrings.ImportingType % os.path.basename(file_path))
             try:
                 # Pass a file object, because lxml does not cope with some
@@ -72,4 +72,4 @@
                 self.openLyrics.xml_to_song(xml)
             except etree.XMLSyntaxError:
                 log.exception(u'XML syntax error in file %s' % file_path)
-                self.log_error(file_path, SongStrings.XMLSyntaxError)
+                self.logError(file_path, SongStrings.XMLSyntaxError)

=== modified file 'openlp/plugins/songs/lib/opensongimport.py'
--- openlp/plugins/songs/lib/opensongimport.py	2011-08-16 08:46:55 +0000
+++ openlp/plugins/songs/lib/opensongimport.py	2011-09-12 20:09:26 +0000
@@ -107,32 +107,32 @@
         """
         SongImport.__init__(self, manager, **kwargs)
 
-    def do_import(self):
-        self.import_wizard.progressBar.setMaximum(len(self.import_source))
-        for filename in self.import_source:
-            if self.stop_import_flag:
+    def doImport(self):
+        self.importWizard.progressBar.setMaximum(len(self.importSource))
+        for filename in self.importSource:
+            if self.stopImportFlag:
                 return
             song_file = open(filename)
-            self.do_import_file(song_file)
+            self.doImportFile(song_file)
             song_file.close()
 
-    def do_import_file(self, file):
+    def doImportFile(self, file):
         """
         Process the OpenSong file - pass in a file-like object, not a file path.
         """
-        self.set_defaults()
+        self.setDefaults()
         try:
             tree = objectify.parse(file)
         except (Error, LxmlError):
-            self.log_error(file.name, SongStrings.XMLSyntaxError)
+            self.logError(file.name, SongStrings.XMLSyntaxError)
             log.exception(u'Error parsing XML')
             return
         root = tree.getroot()
         fields = dir(root)
         decode = {
-            u'copyright': self.add_copyright,
+            u'copyright': self.addCopyright,
             u'ccli': u'ccli_number',
-            u'author': self.parse_author,
+            u'author': self.parseAuthor,
             u'title': u'title',
             u'aka': u'alternate_title',
             u'hymn_number': u'song_number'
@@ -214,7 +214,7 @@
                 verses[verse_tag][verse_num][inst] = []
                 our_verse_order.append([verse_tag, verse_num, inst])
             # Tidy text and remove the ____s from extended words
-            this_line = self.tidy_text(this_line)
+            this_line = self.tidyText(this_line)
             this_line = this_line.replace(u'_', u'')
             this_line = this_line.replace(u'|', u'\n')
             verses[verse_tag][verse_num][inst].append(this_line)
@@ -223,9 +223,9 @@
         for (verse_tag, verse_num, inst) in our_verse_order:
             verse_def = u'%s%s' % (verse_tag, verse_num)
             lines = u'\n'.join(verses[verse_tag][verse_num][inst])
-            self.add_verse(lines, verse_def)
+            self.addVerse(lines, verse_def)
         if not self.verses:
-            self.add_verse('')
+            self.addVerse('')
         # figure out the presentation order, if present
         if u'presentation' in fields and root.presentation:
             order = unicode(root.presentation)
@@ -246,9 +246,9 @@
                 verse_def = u'%s%s' % (verse_tag, verse_num)
                 if verses.has_key(verse_tag) and \
                     verses[verse_tag].has_key(verse_num):
-                    self.verse_order_list.append(verse_def)
+                    self.verseOrderList.append(verse_def)
                 else:
                     log.info(u'Got order %s but not in verse tags, dropping'
                         u'this item from presentation order', verse_def)
         if not self.finish():
-            self.log_error(file.name)
+            self.logError(file.name)

=== modified file 'openlp/plugins/songs/lib/sofimport.py'
--- openlp/plugins/songs/lib/sofimport.py	2011-06-23 23:05:06 +0000
+++ openlp/plugins/songs/lib/sofimport.py	2011-09-12 20:09:26 +0000
@@ -83,32 +83,32 @@
         OooImport.__init__(self, manager, **kwargs)
         self.song = False
 
-    def process_ooo_document(self):
+    def processOooDocument(self):
         """
         Handle the import process for SoF files.
         """
-        self.process_sof_file()
+        self.processSofFile()
 
-    def process_sof_file(self):
+    def processSofFile(self):
         """
         Process the RTF file, a paragraph at a time
         """
-        self.blanklines = 0
-        self.new_song()
+        self.blankLines = 0
+        self.newSong()
         try:
             paragraphs = self.document.getText().createEnumeration()
             while paragraphs.hasMoreElements():
-                if self.stop_import_flag:
+                if self.stopImportFlag:
                     return
                 paragraph = paragraphs.nextElement()
                 if paragraph.supportsService("com.sun.star.text.Paragraph"):
-                    self.process_paragraph(paragraph)
+                    self.processParagraph(paragraph)
         except RuntimeException as exc:
             log.exception(u'Error processing file: %s', exc)
         if not self.finish():
-            self.log_error(self.filepath)
+            self.logError(self.filepath)
 
-    def process_paragraph(self, paragraph):
+    def processParagraph(self, paragraph):
         """
         Process a paragraph.
         In the first book, a paragraph is a single line. In the latter ones
@@ -124,26 +124,26 @@
         while textportions.hasMoreElements():
             textportion = textportions.nextElement()
             if textportion.BreakType in (PAGE_BEFORE, PAGE_BOTH):
-                self.process_paragraph_text(text)
-                self.new_song()
+                self.processParagraphText(text)
+                self.newSong()
                 text = u''
             text += self.process_textportion(textportion)
             if textportion.BreakType in (PAGE_AFTER, PAGE_BOTH):
-                self.process_paragraph_text(text)
-                self.new_song()
+                self.processParagraphText(text)
+                self.newSong()
                 text = u''
-        self.process_paragraph_text(text)
+        self.processParagraphText(text)
 
-    def process_paragraph_text(self, text):
+    def processParagraphText(self, text):
         """
         Split the paragraph text into multiple lines and process
         """
         for line in text.split(u'\n'):
-            self.process_paragraph_line(line)
-        if self.blanklines > 2:
-            self.new_song()
+            self.processParagraphLine(line)
+        if self.blankLines > 2:
+            self.newSong()
 
-    def process_paragraph_line(self, text):
+    def processParagraphLine(self, text):
         """
         Process a single line. Throw away that text which isn't relevant, i.e.
         stuff that appears at the end of the song.
@@ -151,16 +151,16 @@
         """
         text = text.strip()
         if text == u'':
-            self.blanklines += 1
-            if self.blanklines > 1:
+            self.blankLines += 1
+            if self.blankLines > 1:
                 return
             if self.title != u'':
-                self.finish_verse()
+                self.finishVerse()
             return
-        self.blanklines = 0
-        if self.skip_to_close_bracket:
+        self.blankLines = 0
+        if self.skipToCloseBracket:
             if text.endswith(u')'):
-                self.skip_to_close_bracket = False
+                self.skipToCloseBracket = False
             return
         if text.startswith(u'CCL Licence'):
             self.italics = False
@@ -169,24 +169,24 @@
             return
         if text.startswith(u'(NB.') or text.startswith(u'(Regrettably') \
             or text.startswith(u'(From'):
-            self.skip_to_close_bracket = True
+            self.skipToCloseBracket = True
             return
         if text.startswith(u'Copyright'):
-            self.add_copyright(text)
+            self.addCopyright(text)
             return
         if text == u'(Repeat)':
-            self.finish_verse()
-            self.repeat_verse()
+            self.finishVerse()
+            self.repeatVerse()
             return
         if self.title == u'':
             if self.copyright == u'':
-                self.add_sof_author(text)
+                self.addSofAuthor(text)
             else:
-                self.add_copyright(text)
+                self.addCopyright(text)
             return
-        self.add_verse_line(text)
+        self.addVerseLine(text)
 
-    def process_textportion(self, textportion):
+    def processTextPortion(self, textportion):
         """
         Process a text portion. Here we just get the text and detect if
         it's bold or italics. If it's bold then its a song number or song title.
@@ -199,53 +199,53 @@
             return text
         if textportion.CharWeight == BOLD:
             boldtext = text.strip()
-            if boldtext.isdigit() and self.song_number == '':
-                self.add_songnumber(boldtext)
+            if boldtext.isdigit() and self.songNumber == '':
+                self.addSongNumber(boldtext)
                 return u''
             if self.title == u'':
                 text = self.uncap_text(text)
-                self.add_title(text)
+                self.addTitle(text)
             return text
         if text.strip().startswith(u'('):
             return text
         self.italics = (textportion.CharPosture == ITALIC)
         return text
 
-    def new_song(self):
+    def newSong(self):
         """
         A change of song. Store the old, create a new
         ... but only if the last song was complete. If not, stick with it
         """
         if self.song:
-            self.finish_verse()
-            if not self.check_complete():
+            self.finishVerse()
+            if not self.checkComplete():
                 return
             self.finish()
         self.song = True
-        self.set_defaults()
-        self.skip_to_close_bracket = False
-        self.is_chorus = False
+        self.setDefaults()
+        self.skipToCloseBracket = False
+        self.isChorus = False
         self.italics = False
-        self.currentverse = u''
+        self.currentVerse = u''
 
-    def add_songnumber(self, song_no):
+    def addSongNumber(self, song_no):
         """
         Add a song number, store as alternate title. Also use the song
         number to work out which songbook we're in
         """
-        self.song_number = song_no
-        self.alternate_title = song_no + u'.'
-        self.song_book_pub = u'Kingsway Publications'
+        self.songNumber = song_no
+        self.alternateTitle = song_no + u'.'
+        self.songBook_pub = u'Kingsway Publications'
         if int(song_no) <= 640:
-            self.song_book = u'Songs of Fellowship 1'
+            self.songBook = u'Songs of Fellowship 1'
         elif int(song_no) <= 1150:
-            self.song_book = u'Songs of Fellowship 2'
+            self.songBook = u'Songs of Fellowship 2'
         elif int(song_no) <= 1690:
-            self.song_book = u'Songs of Fellowship 3'
+            self.songBook = u'Songs of Fellowship 3'
         else:
-            self.song_book = u'Songs of Fellowship 4'
+            self.songBook = u'Songs of Fellowship 4'
 
-    def add_title(self, text):
+    def addTitle(self, text):
         """
         Add the title to the song. Strip some leading/trailing punctuation that
         we don't want in a title
@@ -256,9 +256,9 @@
         if title.endswith(u','):
             title = title[:-1]
         self.title = title
-        self.import_wizard.incrementProgressBar(u'Processing song ' + title, 0)
+        self.importWizard.incrementProgressBar(u'Processing song ' + title, 0)
 
-    def add_sof_author(self, text):
+    def addSofAuthor(self, text):
         """
         Add the author. OpenLP stores them individually so split by 'and', '&'
         and comma.
@@ -266,42 +266,42 @@
         "Mr Smith" and "Mrs Smith".
         """
         text = text.replace(u' and ', u' & ')
-        self.parse_author(text)
+        self.parseAuthor(text)
 
-    def add_verse_line(self, text):
+    def addVerseLine(self, text):
         """
         Add a line to the current verse. If the formatting has changed and
         we're beyond the second line of first verse, then this indicates
         a change of verse. Italics are a chorus
         """
-        if self.italics != self.is_chorus and ((len(self.verses) > 0) or
-            (self.currentverse.count(u'\n') > 1)):
-            self.finish_verse()
+        if self.italics != self.isChorus and ((len(self.verses) > 0) or
+            (self.currentVerse.count(u'\n') > 1)):
+            self.finishVerse()
         if self.italics:
-            self.is_chorus = True
-        self.currentverse += text + u'\n'
+            self.isChorus = True
+        self.currentVerse += text + u'\n'
 
-    def finish_verse(self):
+    def finishVerse(self):
         """
         Verse is finished, store it. Note in book 1+2, some songs are formatted
         incorrectly. Here we try and split songs with missing line breaks into
         the correct number of verses.
         """
-        if self.currentverse.strip() == u'':
+        if self.currentVerse.strip() == u'':
             return
-        if self.is_chorus:
+        if self.isChorus:
             versetag = u'C'
             splitat = None
         else:
             versetag = u'V'
-            splitat = self.verse_splits(self.song_number)
+            splitat = self.verseSplits(self.songNumber)
         if splitat:
             ln = 0
             verse = u''
-            for line in self.currentverse.split(u'\n'):
+            for line in self.currentVerse.split(u'\n'):
                 ln += 1
                 if line == u'' or ln > splitat:
-                    self.add_sof_verse(verse, versetag)
+                    self.addSofVerse(verse, versetag)
                     ln = 0
                     if line:
                         verse = line + u'\n'
@@ -310,19 +310,19 @@
                 else:
                     verse += line + u'\n'
             if verse:
-                self.add_sof_verse(verse, versetag)
+                self.addSofVerse(verse, versetag)
         else:
-            self.add_sof_verse(self.currentverse, versetag)
-        self.currentverse = u''
-        self.is_chorus = False
-
-    def add_sof_verse(self, lyrics, tag):
-        self.add_verse(lyrics, tag)
-        if not self.is_chorus and u'C1' in self.verse_order_list_generated:
-            self.verse_order_list_generated.append(u'C1')
-            self.verse_order_list_generated_useful = True
-
-    def uncap_text(self, text):
+            self.addSofVerse(self.currentVerse, versetag)
+        self.currentVerse = u''
+        self.isChorus = False
+
+    def addSofVerse(self, lyrics, tag):
+        self.addVerse(lyrics, tag)
+        if not self.isChorus and u'C1' in self.verseOrderListGenerated:
+            self.verseOrderListGenerated.append(u'C1')
+            self.verseOrderListGenerated_useful = True
+
+    def uncapText(self, text):
         """
         Words in the title are in all capitals, so we lowercase them.
         However some of these words, e.g. referring to God need a leading
@@ -348,7 +348,7 @@
         text = u''.join(textarr)
         return text
 
-    def verse_splits(self, song_number):
+    def verseSplits(self, song_number):
         """
         Because someone at Kingsway forgot to check the 1+2 RTF file,
         some verses were not formatted correctly.

=== modified file 'openlp/plugins/songs/lib/songbeamerimport.py'
--- openlp/plugins/songs/lib/songbeamerimport.py	2011-07-07 18:03:12 +0000
+++ openlp/plugins/songs/lib/songbeamerimport.py	2011-09-12 20:09:26 +0000
@@ -91,27 +91,27 @@
         (re.compile(u'<align.*?>'), u''),
         (re.compile(u'<valign.*?>'), u'')
     ]
-    
+
     def __init__(self, manager, **kwargs):
         """
         Initialise the Song Beamer importer.
         """
         SongImport.__init__(self, manager, **kwargs)
 
-    def do_import(self):
+    def doImport(self):
         """
         Receive a single file or a list of files to import.
         """
-        self.import_wizard.progressBar.setMaximum(len(self.import_source))
-        if not isinstance(self.import_source, list):
+        self.importWizard.progressBar.setMaximum(len(self.importSource))
+        if not isinstance(self.importSource, list):
             return
-        for file in self.import_source:
+        for file in self.importSource:
             # TODO: check that it is a valid SongBeamer file
-            if self.stop_import_flag:
+            if self.stopImportFlag:
                 return
-            self.set_defaults()
-            self.current_verse = u''
-            self.current_verse_type = VerseType.Tags[VerseType.Verse]
+            self.setDefaults()
+            self.currentVerse = u''
+            self.currentVerseType = VerseType.Tags[VerseType.Verse]
             read_verses = False
             file_name = os.path.split(file)[1]
             if os.path.isfile(file):
@@ -119,48 +119,48 @@
                 details = chardet.detect(detect_file.read())
                 detect_file.close()
                 infile = codecs.open(file, u'r', details['encoding'])
-                songData = infile.readlines()
+                song_data = infile.readlines()
                 infile.close()
             else:
                 continue
             self.title = file_name.split('.sng')[0]
             read_verses = False
-            for line in songData:
+            for line in song_data:
                 # Just make sure that the line is of the type 'Unicode'.
                 line = unicode(line).strip()
                 if line.startswith(u'#') and not read_verses:
-                    self.parse_tags(line)
+                    self.parseTags(line)
                 elif line.startswith(u'---'):
-                    if self.current_verse:
-                        self.replace_html_tags()
-                        self.add_verse(self.current_verse,
-                            self.current_verse_type)
-                        self.current_verse = u''
-                        self.current_verse_type = VerseType.Tags[VerseType.Verse]
+                    if self.currentVerse:
+                        self.replaceHtmlTags()
+                        self.addVerse(self.currentVerse,
+                            self.currentVerseType)
+                        self.currentVerse = u''
+                        self.currentVerseType = VerseType.Tags[VerseType.Verse]
                     read_verses = True
                     verse_start = True
                 elif read_verses:
                     if verse_start:
                         verse_start = False
-                        if not self.check_verse_marks(line):
-                            self.current_verse = line + u'\n'
+                        if not self.checkVerseMarks(line):
+                            self.currentVerse = line + u'\n'
                     else:
-                        self.current_verse += line + u'\n'
-            if self.current_verse:
-                self.replace_html_tags()
-                self.add_verse(self.current_verse, self.current_verse_type)
+                        self.currentVerse += line + u'\n'
+            if self.currentVerse:
+                self.replaceHtmlTags()
+                self.addVerse(self.currentVerse, self.currentVerseType)
             if not self.finish():
-                self.log_error(file)
+                self.logError(file)
 
-    def replace_html_tags(self):
+    def replaceHtmlTags(self):
         """
         This can be called to replace SongBeamer's specific (html) tags with
         OpenLP's specific (html) tags.
         """
         for pair in SongBeamerImport.HTML_TAG_PAIRS:
-            self.current_verse = pair[0].sub(pair[1], self.current_verse)
+            self.currentVerse = pair[0].sub(pair[1], self.currentVerse)
 
-    def parse_tags(self, line):
+    def parseTags(self, line):
         """
         Parses a meta data line.
 
@@ -176,11 +176,11 @@
         if not tag_val[0] or not tag_val[1]:
             return
         if tag_val[0] == u'#(c)':
-            self.add_copyright(tag_val[1])
+            self.addCopyright(tag_val[1])
         elif tag_val[0] == u'#AddCopyrightInfo':
             pass
         elif tag_val[0] == u'#Author':
-            self.parse_author(tag_val[1])
+            self.parseAuthor(tag_val[1])
         elif tag_val[0] == u'#BackgroundImage':
             pass
         elif tag_val[0] == u'#Bible':
@@ -188,7 +188,7 @@
         elif tag_val[0] == u'#Categories':
             self.topics = tag_val[1].split(',')
         elif tag_val[0] == u'#CCLI':
-            self.ccli_number = tag_val[1]
+            self.ccliNumber = tag_val[1]
         elif tag_val[0] == u'#Chords':
             pass
         elif tag_val[0] == u'#ChurchSongID':
@@ -220,7 +220,7 @@
         elif tag_val[0] == u'#LangCount':
             pass
         elif tag_val[0] == u'#Melody':
-            self.parse_author(tag_val[1])
+            self.parseAuthor(tag_val[1])
         elif tag_val[0] == u'#NatCopyright':
             pass
         elif tag_val[0] == u'#OTitle':
@@ -235,10 +235,10 @@
             song_book_pub = tag_val[1]
         elif tag_val[0] == u'#Songbook' or tag_val[0] == u'#SongBook':
             book_data = tag_val[1].split(u'/')
-            self.song_book_name = book_data[0].strip()
+            self.songBookName = book_data[0].strip()
             if len(book_data) == 2:
                 number = book_data[1].strip()
-                self.song_number = number if number.isdigit() else u''
+                self.songNumber = number if number.isdigit() else u''
         elif tag_val[0] == u'#Speed':
             pass
         elif tag_val[0] == u'Tempo':
@@ -269,7 +269,7 @@
             # TODO: add the verse order.
             pass
 
-    def check_verse_marks(self, line):
+    def checkVerseMarks(self, line):
         """
         Check and add the verse's MarkType. Returns ``True`` if the given line
         contains a correct verse mark otherwise ``False``.
@@ -279,10 +279,10 @@
         """
         marks = line.split(u' ')
         if len(marks) <= 2 and marks[0] in SongBeamerTypes.MarkTypes:
-            self.current_verse_type = SongBeamerTypes.MarkTypes[marks[0]]
+            self.currentVerseType = SongBeamerTypes.MarkTypes[marks[0]]
             if len(marks) == 2:
                 # If we have a digit, we append it to current_verse_type.
                 if marks[1].isdigit():
-                    self.current_verse_type += marks[1]
+                    self.currentVerseType += marks[1]
             return True
         return False

=== modified file 'openlp/plugins/songs/lib/songimport.py'
--- openlp/plugins/songs/lib/songimport.py	2011-07-07 18:03:12 +0000
+++ openlp/plugins/songs/lib/songimport.py	2011-09-12 20:09:26 +0000
@@ -26,11 +26,14 @@
 ###############################################################################
 import logging
 import re
+import shutil
+import os
 
 from PyQt4 import QtCore
 
 from openlp.core.lib import Receiver, translate
 from openlp.core.ui.wizard import WizardStrings
+from openlp.core.utils import AppLocation
 from openlp.plugins.songs.lib import clean_song, VerseType
 from openlp.plugins.songs.lib.db import Song, Author, Topic, Book, MediaFile
 from openlp.plugins.songs.lib.ui import SongStrings
@@ -58,51 +61,51 @@
         self.manager = manager
         QtCore.QObject.__init__(self)
         if kwargs.has_key(u'filename'):
-            self.import_source = kwargs[u'filename']
+            self.importSource = kwargs[u'filename']
         elif kwargs.has_key(u'filenames'):
-            self.import_source = kwargs[u'filenames']
+            self.importSource = kwargs[u'filenames']
         else:
             raise KeyError(u'Keyword arguments "filename[s]" not supplied.')
-        log.debug(self.import_source)
-        self.import_wizard = None
+        log.debug(self.importSource)
+        self.importWizard = None
         self.song = None
-        self.stop_import_flag = False
-        self.set_defaults()
-        self.error_log = []
+        self.stopImportFlag = False
+        self.setDefaults()
+        self.errorLog = []
         QtCore.QObject.connect(Receiver.get_receiver(),
-            QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import)
+            QtCore.SIGNAL(u'openlp_stop_wizard'), self.stopImport)
 
-    def set_defaults(self):
+    def setDefaults(self):
         """
         Create defaults for properties - call this before each song
         if importing many songs at once to ensure a clean beginning
         """
         self.title = u''
-        self.song_number = u''
-        self.alternate_title = u''
+        self.songNumber = u''
+        self.alternateTitle = u''
         self.copyright = u''
         self.comments = u''
-        self.theme_name = u''
-        self.ccli_number = u''
+        self.themeName = u''
+        self.ccliNumber = u''
         self.authors = []
         self.topics = []
-        self.media_files = []
-        self.song_book_name = u''
-        self.song_book_pub = u''
-        self.verse_order_list_generated_useful = False
-        self.verse_order_list_generated = []
-        self.verse_order_list = []
+        self.mediaFiles = []
+        self.songBookName = u''
+        self.songBookPub = u''
+        self.verseOrderListGeneratedUseful = False
+        self.verseOrderListGenerated = []
+        self.verseOrderList = []
         self.verses = []
-        self.verse_counts = {}
-        self.copyright_string = unicode(translate(
+        self.verseCounts = {}
+        self.copyrightString = unicode(translate(
             'SongsPlugin.SongImport', 'copyright'))
 
-    def log_error(self, filepath, reason=SongStrings.SongIncomplete):
+    def logError(self, filepath, reason=SongStrings.SongIncomplete):
         """
         This should be called, when a song could not be imported.
 
         ``filepath``
-            This should be the file path if ``self.import_source`` is a list
+            This should be the file path if ``self.importSource`` is a list
             with different files. If it is not a list, but a  single file (for
             instance a database), then this should be the song's title.
 
@@ -110,30 +113,30 @@
             The reason, why the import failed. The string should be as
             informative as possible.
         """
-        self.set_defaults()
-        if self.import_wizard is None:
+        self.setDefaults()
+        if self.importWizard is None:
             return
-        if self.import_wizard.errorReportTextEdit.isHidden():
-            self.import_wizard.errorReportTextEdit.setText(
+        if self.importWizard.errorReportTextEdit.isHidden():
+            self.importWizard.errorReportTextEdit.setText(
                 translate('SongsPlugin.SongImport',
                 'The following songs could not be imported:'))
-            self.import_wizard.errorReportTextEdit.setVisible(True)
-            self.import_wizard.errorCopyToButton.setVisible(True)
-            self.import_wizard.errorSaveToButton.setVisible(True)
-        self.import_wizard.errorReportTextEdit.append(
+            self.importWizard.errorReportTextEdit.setVisible(True)
+            self.importWizard.errorCopyToButton.setVisible(True)
+            self.importWizard.errorSaveToButton.setVisible(True)
+        self.importWizard.errorReportTextEdit.append(
             u'- %s (%s)' % (filepath, reason))
 
-    def stop_import(self):
+    def stopImport(self):
         """
         Sets the flag for importers to stop their import
         """
         log.debug(u'Stopping songs import')
-        self.stop_import_flag = True
+        self.stopImportFlag = True
 
     def register(self, import_wizard):
-        self.import_wizard = import_wizard
+        self.importWizard = import_wizard
 
-    def tidy_text(self, text):
+    def tidyText(self, text):
         """
         Get rid of some dodgy unicode and formatting characters we're not
         interested in. Some can be converted to ascii.
@@ -151,34 +154,34 @@
         text = re.sub(r' ?(\n{5}|\f)+ ?', u'\f', text)
         return text
 
-    def process_song_text(self, text):
+    def processSongText(self, text):
         verse_texts = text.split(u'\n\n')
         for verse_text in verse_texts:
             if verse_text.strip() != u'':
-                self.process_verse_text(verse_text.strip())
+                self.processVerseText(verse_text.strip())
 
-    def process_verse_text(self, text):
+    def processVerseText(self, text):
         lines = text.split(u'\n')
-        if text.lower().find(self.copyright_string) >= 0 \
+        if text.lower().find(self.copyrightString) >= 0 \
             or text.find(unicode(SongStrings.CopyrightSymbol)) >= 0:
             copyright_found = False
             for line in lines:
                 if (copyright_found or
-                    line.lower().find(self.copyright_string) >= 0 or
+                    line.lower().find(self.copyrightString) >= 0 or
                     line.find(unicode(SongStrings.CopyrightSymbol)) >= 0):
                     copyright_found = True
-                    self.add_copyright(line)
+                    self.addCopyright(line)
                 else:
-                    self.parse_author(line)
+                    self.parseAuthor(line)
             return
         if len(lines) == 1:
-            self.parse_author(lines[0])
+            self.parseAuthor(lines[0])
             return
         if not self.title:
             self.title = lines[0]
-        self.add_verse(text)
+        self.addVerse(text)
 
-    def add_copyright(self, copyright):
+    def addCopyright(self, copyright):
         """
         Build the copyright field
         """
@@ -188,7 +191,7 @@
             self.copyright += ' '
         self.copyright += copyright
 
-    def parse_author(self, text):
+    def parseAuthor(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
@@ -204,9 +207,9 @@
                 if author2.endswith(u'.'):
                     author2 = author2[:-1]
                 if author2:
-                    self.add_author(author2)
+                    self.addAuthor(author2)
 
-    def add_author(self, author):
+    def addAuthor(self, author):
         """
         Add an author to the list
         """
@@ -214,15 +217,15 @@
             return
         self.authors.append(author)
 
-    def add_media_file(self, filename):
+    def addMediaFile(self, filename, weight=0):
         """
         Add a media file to the list
         """
-        if filename in self.media_files:
+        if filename in map(lambda x: x[0], self.mediaFiles):
             return
-        self.media_files.append(filename)
+        self.mediaFiles.append((filename, weight))
 
-    def add_verse(self, verse_text, verse_def=u'v', lang=None):
+    def addVerse(self, verse_text, verse_def=u'v', lang=None):
         """
         Add a verse. This is the whole verse, lines split by \\n. It will also
         attempt to detect duplicates. In this case it will just add to the verse
@@ -241,29 +244,29 @@
         """
         for (old_verse_def, old_verse, old_lang) in self.verses:
             if old_verse.strip() == verse_text.strip():
-                self.verse_order_list_generated.append(old_verse_def)
-                self.verse_order_list_generated_useful = True
+                self.verseOrderListGenerated.append(old_verse_def)
+                self.verseOrderListGeneratedUseful = True
                 return
-        if verse_def[0] in self.verse_counts:
-            self.verse_counts[verse_def[0]] += 1
+        if verse_def[0] in self.verseCounts:
+            self.verseCounts[verse_def[0]] += 1
         else:
-            self.verse_counts[verse_def[0]] = 1
+            self.verseCounts[verse_def[0]] = 1
         if len(verse_def) == 1:
-            verse_def += unicode(self.verse_counts[verse_def[0]])
-        elif int(verse_def[1:]) > self.verse_counts[verse_def[0]]:
-            self.verse_counts[verse_def[0]] = int(verse_def[1:])
+            verse_def += unicode(self.verseCounts[verse_def[0]])
+        elif int(verse_def[1:]) > self.verseCounts[verse_def[0]]:
+            self.verseCounts[verse_def[0]] = int(verse_def[1:])
         self.verses.append([verse_def, verse_text.rstrip(), lang])
-        self.verse_order_list_generated.append(verse_def)
+        self.verseOrderListGenerated.append(verse_def)
 
-    def repeat_verse(self):
+    def repeatVerse(self):
         """
         Repeat the previous verse in the verse order
         """
-        self.verse_order_list_generated.append(
-            self.verse_order_list_generated[-1])
-        self.verse_order_list_generated_useful = True
+        self.verseOrderListGenerated.append(
+            self.verseOrderListGenerated[-1])
+        self.verseOrderListGeneratedUseful = True
 
-    def check_complete(self):
+    def checkComplete(self):
         """
         Check the mandatory fields are entered (i.e. title and a verse)
         Author not checked here, if no author then "Author unknown" is
@@ -278,21 +281,21 @@
         """
         All fields have been set to this song. Write the song to disk.
         """
-        if not self.check_complete():
-            self.set_defaults()
+        if not self.checkComplete():
+            self.setDefaults()
             return False
         log.info(u'committing song %s to database', self.title)
         song = Song()
         song.title = self.title
-        if self.import_wizard is not None:
-            self.import_wizard.incrementProgressBar(
+        if self.importWizard is not None:
+            self.importWizard.incrementProgressBar(
                 WizardStrings.ImportingType % song.title)
-        song.alternate_title = self.alternate_title
+        song.alternate_title = self.alternateTitle
         # Values will be set when cleaning the song.
         song.search_title = u''
         song.search_lyrics = u''
         song.verse_order = u''
-        song.song_number = self.song_number
+        song.song_number = self.songNumber
         verses_changed_to_other = {}
         sxml = SongXML()
         other_count = 1
@@ -310,18 +313,18 @@
                 verse_def = new_verse_def
             sxml.add_verse_to_lyrics(verse_tag, verse_def[1:], verse_text, lang)
         song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
-        if not len(self.verse_order_list) and \
-            self.verse_order_list_generated_useful:
-            self.verse_order_list = self.verse_order_list_generated
-        for i, current_verse_def in enumerate(self.verse_order_list):
+        if not len(self.verseOrderList) and \
+            self.verseOrderListGeneratedUseful:
+            self.verseOrderList = self.verseOrderListGenerated
+        for i, current_verse_def in enumerate(self.verseOrderList):
             if verses_changed_to_other.has_key(current_verse_def):
-                self.verse_order_list[i] = \
+                self.verseOrderList[i] = \
                     verses_changed_to_other[current_verse_def]
-        song.verse_order = u' '.join(self.verse_order_list)
+        song.verse_order = u' '.join(self.verseOrderList)
         song.copyright = self.copyright
         song.comments = self.comments
-        song.theme_name = self.theme_name
-        song.ccli_number = self.ccli_number
+        song.theme_name = self.themeName
+        song.ccli_number = self.ccliNumber
         for authortext in self.authors:
             author = self.manager.get_object_filtered(Author,
                 Author.display_name == authortext)
@@ -330,17 +333,12 @@
                     last_name=authortext.split(u' ')[-1],
                     first_name=u' '.join(authortext.split(u' ')[:-1]))
             song.authors.append(author)
-        for filename in self.media_files:
-            media_file = self.manager.get_object_filtered(MediaFile,
-                MediaFile.file_name == filename)
-            if not media_file:
-                song.media_files.append(MediaFile.populate(file_name=filename))
-        if self.song_book_name:
+        if self.songBookName:
             song_book = self.manager.get_object_filtered(Book,
-                Book.name == self.song_book_name)
+                Book.name == self.songBookName)
             if song_book is None:
-                song_book = Book.populate(name=self.song_book_name,
-                    publisher=self.song_book_pub)
+                song_book = Book.populate(name=self.songBookName,
+                    publisher=self.songBookPub)
             song.book = song_book
         for topictext in self.topics:
             if not topictext:
@@ -350,38 +348,42 @@
             if topic is None:
                 topic = Topic.populate(name=topictext)
             song.topics.append(topic)
+        # We need to save the song now, before adding the media files, so that
+        # we know where to save the media files to.
         clean_song(self.manager, song)
         self.manager.save_object(song)
-        self.set_defaults()
+        # Now loop through the media files, copy them to the correct location,
+        # and save the song again.
+        for filename, weight in self.mediaFiles:
+            media_file = self.manager.get_object_filtered(MediaFile,
+                MediaFile.file_name == filename)
+            if not media_file:
+                if os.path.dirname(filename):
+                    filename = self.copyMediaFile(song.id, filename)
+                song.media_files.append(
+                    MediaFile.populate(file_name=filename, weight=weight)
+                )
+        self.manager.save_object(song)
+        self.setDefaults()
         return True
 
-    def print_song(self):
-        """
-        For debugging
-        """
-        print u'========================================' \
-            + u'========================================'
-        print u'TITLE: ' + self.title
-        print u'ALT TITLE: ' + self.alternate_title
-        for (verse_def, verse_text, lang) in self.verses:
-            print u'VERSE ' + verse_def + u': ' + verse_text
-        print u'ORDER: ' + u' '.join(self.verse_order_list)
-        print u'GENERATED ORDER: ' + u' '.join(self.verse_order_list_generated)
-        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.comments:
-            print u'COMMENTS: ' + self.comments
-        if self.theme_name:
-            print u'THEME: ' + self.theme_name
-        if self.ccli_number:
-            print u'CCLI: ' + self.ccli_number
+    def copyMediaFile(self, song_id, filename):
+        """
+        This method copies the media file to the correct location and returns
+        the new file location.
+
+        ``filename``
+            The file to copy.
+        """
+        if not hasattr(self, u'save_path'):
+            self.save_path = os.path.join(
+                AppLocation.get_section_data_path(
+                    self.importWizard.plugin.name),
+                'audio', str(song_id))
+        if not os.path.exists(self.save_path):
+            os.makedirs(self.save_path)
+        if not filename.startswith(self.save_path):
+            oldfile, filename = filename, os.path.join(self.save_path,
+                os.path.split(filename)[1])
+            shutil.copyfile(oldfile, filename)
+        return filename

=== modified file 'openlp/plugins/songs/lib/songshowplusimport.py'
--- openlp/plugins/songs/lib/songshowplusimport.py	2011-08-29 13:08:50 +0000
+++ openlp/plugins/songs/lib/songshowplusimport.py	2011-09-12 20:09:26 +0000
@@ -95,120 +95,120 @@
         """
         SongImport.__init__(self, manager, **kwargs)
 
-    def do_import(self):
+    def doImport(self):
         """
         Receive a single file or a list of files to import.
         """
-        if not isinstance(self.import_source, list):
+        if not isinstance(self.importSource, list):
             return
-        self.import_wizard.progressBar.setMaximum(len(self.import_source))
-        for file in self.import_source:
-            if self.stop_import_flag:
+        self.importWizard.progressBar.setMaximum(len(self.importSource))
+        for file in self.importSource:
+            if self.stopImportFlag:
                 return
             self.sspVerseOrderList = []
-            otherCount = 0
-            otherList = {}
+            other_count = 0
+            other_list = {}
             file_name = os.path.split(file)[1]
-            self.import_wizard.incrementProgressBar(
+            self.importWizard.incrementProgressBar(
                 WizardStrings.ImportingType % file_name, 0)
-            songData = open(file, 'rb')
+            song_data = open(file, 'rb')
             while True:
-                blockKey, = struct.unpack("I", songData.read(4))
+                block_key, = struct.unpack("I", song_data.read(4))
                 # The file ends with 4 NUL's
-                if blockKey == 0:
+                if block_key == 0:
                     break
-                nextBlockStarts, = struct.unpack("I", songData.read(4))
-                nextBlockStarts += songData.tell()
-                if blockKey in (VERSE, CHORUS, BRIDGE):
-                    null, verseNo,  = struct.unpack("BB", songData.read(2))
-                elif blockKey == CUSTOM_VERSE:
-                    null, verseNameLength, = struct.unpack("BB",
-                        songData.read(2))
-                    verseName = songData.read(verseNameLength)
-                lengthDescriptorSize, = struct.unpack("B", songData.read(1))
-                log.debug(lengthDescriptorSize)
+                next_block_starts, = struct.unpack("I", song_data.read(4))
+                next_block_starts += song_data.tell()
+                if block_key in (VERSE, CHORUS, BRIDGE):
+                    null, verse_no, = struct.unpack("BB", song_data.read(2))
+                elif block_key == CUSTOM_VERSE:
+                    null, verse_name_length, = struct.unpack("BB",
+                        song_data.read(2))
+                    verse_name = song_data.read(verse_name_length)
+                length_descriptor_size, = struct.unpack("B", song_data.read(1))
+                log.debug(length_descriptor_size)
                 # Detect if/how long the length descriptor is
-                if lengthDescriptorSize == 12 or lengthDescriptorSize == 20:
-                    lengthDescriptor, = struct.unpack("I", songData.read(4))
-                elif lengthDescriptorSize == 2:
-                    lengthDescriptor = 1
-                elif lengthDescriptorSize == 9:
-                    lengthDescriptor = 0
+                if length_descriptor_size == 12 or length_descriptor_size == 20:
+                    length_descriptor, = struct.unpack("I", song_data.read(4))
+                elif length_descriptor_size == 2:
+                    length_descriptor = 1
+                elif length_descriptor_size == 9:
+                    length_descriptor = 0
                 else:
-                    lengthDescriptor, = struct.unpack("B", songData.read(1))
-                log.debug(lengthDescriptorSize)
-                data = songData.read(lengthDescriptor)
-                if blockKey == TITLE:
+                    length_descriptor, = struct.unpack("B", song_data.read(1))
+                log.debug(length_descriptor_size)
+                data = song_data.read(length_descriptor)
+                if block_key == TITLE:
                     self.title = unicode(data, u'cp1252')
-                elif blockKey == AUTHOR:
+                elif block_key == AUTHOR:
                     authors = data.split(" / ")
                     for author in authors:
                         if author.find(",") !=-1:
                             authorParts = author.split(", ")
                             author = authorParts[1] + " " + authorParts[0]
-                        self.parse_author(unicode(author, u'cp1252'))
-                elif blockKey == COPYRIGHT:
-                    self.add_copyright(unicode(data, u'cp1252'))
-                elif blockKey == CCLI_NO:
-                    self.ccli_number = int(data)
-                elif blockKey == VERSE:
-                    self.add_verse(unicode(data, u'cp1252'),
-                        "%s%s" % (VerseType.Tags[VerseType.Verse], verseNo))
-                elif blockKey == CHORUS:
-                    self.add_verse(unicode(data, u'cp1252'),
-                        "%s%s" % (VerseType.Tags[VerseType.Chorus], verseNo))
-                elif blockKey == BRIDGE:
-                    self.add_verse(unicode(data, u'cp1252'),
-                        "%s%s" % (VerseType.Tags[VerseType.Bridge], verseNo))
-                elif blockKey == TOPIC:
+                        self.parseAuthor(unicode(author, u'cp1252'))
+                elif block_key == COPYRIGHT:
+                    self.addCopyright(unicode(data, u'cp1252'))
+                elif block_key == CCLI_NO:
+                    self.ccliNumber = int(data)
+                elif block_key == VERSE:
+                    self.addVerse(unicode(data, u'cp1252'),
+                        "%s%s" % (VerseType.Tags[VerseType.Verse], verse_no))
+                elif block_key == CHORUS:
+                    self.addVerse(unicode(data, u'cp1252'),
+                        "%s%s" % (VerseType.Tags[VerseType.Chorus], verse_no))
+                elif block_key == BRIDGE:
+                    self.addVerse(unicode(data, u'cp1252'),
+                        "%s%s" % (VerseType.Tags[VerseType.Bridge], verse_no))
+                elif block_key == TOPIC:
                     self.topics.append(unicode(data, u'cp1252'))
-                elif blockKey == COMMENTS:
+                elif block_key == COMMENTS:
                     self.comments = unicode(data, u'cp1252')
-                elif blockKey == VERSE_ORDER:
-                    verseTag = self.toOpenLPVerseTag(data, True)
-                    if verseTag:
-                        if not isinstance(verseTag, unicode):
-                            verseTag = unicode(verseTag, u'cp1252')
-                        self.sspVerseOrderList.append(verseTag)
-                elif blockKey == SONG_BOOK:
-                    self.song_book_name = unicode(data, u'cp1252')
-                elif blockKey == SONG_NUMBER:
-                    self.song_number = ord(data)
-                elif blockKey == CUSTOM_VERSE:
-                    verseTag = self.toOpenLPVerseTag(verseName)
-                    self.add_verse(unicode(data, u'cp1252'), verseTag)
+                elif block_key == VERSE_ORDER:
+                    verse_tag = self.toOpenLPVerseTag(data, True)
+                    if verse_tag:
+                        if not isinstance(verse_tag, unicode):
+                            verse_tag = unicode(verse_tag, u'cp1252')
+                        self.sspVerseOrderList.append(verse_tag)
+                elif block_key == SONG_BOOK:
+                    self.songBookName = unicode(data, u'cp1252')
+                elif block_key == SONG_NUMBER:
+                    self.songNumber = ord(data)
+                elif block_key == CUSTOM_VERSE:
+                    verse_tag = self.toOpenLPVerseTag(verse_name)
+                    self.addVerse(unicode(data, u'cp1252'), verse_tag)
                 else:
                     log.debug("Unrecognised blockKey: %s, data: %s"
-                        % (blockKey, data))
-                    songData.seek(nextBlockStarts)
-            self.verse_order_list = self.sspVerseOrderList
-            songData.close()
+                        % (block_key, data))
+                    song_data.seek(next_block_starts)
+            self.verseOrderList = self.sspVerseOrderList
+            song_data.close()
             if not self.finish():
-                self.log_error(file)
+                self.logError(file)
 
-    def toOpenLPVerseTag(self, verseName, ignoreUnique=False):
-        if verseName.find(" ") != -1:
-            verseParts = verseName.split(" ")
-            verseType = verseParts[0]
-            verseNumber = verseParts[1]
-        else:
-            verseType = verseName
-            verseNumber = "1"
-        verseType = verseType.lower()
-        if verseType == "verse":
-            verseTag = VerseType.Tags[VerseType.Verse]
-        elif verseType == "chorus":
-            verseTag = VerseType.Tags[VerseType.Chorus]
-        elif verseType == "bridge":
-            verseTag = VerseType.Tags[VerseType.Bridge]
-        elif verseType == "pre-chorus":
-            verseTag = VerseType.Tags[VerseType.PreChorus]
-        else:
-            if not self.otherList.has_key(verseName):
-                if ignoreUnique:
+    def toOpenLPVerseTag(self, verse_name, ignore_unique=False):
+        if verse_name.find(" ") != -1:
+            verse_parts = verse_name.split(" ")
+            verse_type = verse_parts[0]
+            verse_number = verse_parts[1]
+        else:
+            verse_type = verse_name
+            verse_number = "1"
+        verse_type = verse_type.lower()
+        if verse_type == "verse":
+            verse_tag = VerseType.Tags[VerseType.Verse]
+        elif verse_type == "chorus":
+            verse_tag = VerseType.Tags[VerseType.Chorus]
+        elif verse_type == "bridge":
+            verse_tag = VerseType.Tags[VerseType.Bridge]
+        elif verse_type == "pre-chorus":
+            verse_tag = VerseType.Tags[VerseType.PreChorus]
+        else:
+            if not self.otherList.has_key(verse_name):
+                if ignore_unique:
                     return None
                 self.otherCount = self.otherCount + 1
-                self.otherList[verseName] = str(self.otherCount)
-            verseTag = VerseType.Tags[VerseType.Other]
-            verseNumber = self.otherList[verseName]
-        return verseTag + verseNumber
+                self.otherList[verse_name] = str(self.otherCount)
+            verse_tag = VerseType.Tags[VerseType.Other]
+            verse_number = self.otherList[verse_name]
+        return verse_tag + verse_number

=== modified file 'openlp/plugins/songs/lib/wowimport.py'
--- openlp/plugins/songs/lib/wowimport.py	2011-08-16 00:59:45 +0000
+++ openlp/plugins/songs/lib/wowimport.py	2011-09-12 20:09:26 +0000
@@ -98,58 +98,58 @@
         """
         SongImport.__init__(self, manager, **kwargs)
 
-    def do_import(self):
+    def doImport(self):
         """
         Receive a single file or a list of files to import.
         """
-        if isinstance(self.import_source, list):
-            self.import_wizard.progressBar.setMaximum(len(self.import_source))
-            for file in self.import_source:
-                if self.stop_import_flag:
+        if isinstance(self.importSource, list):
+            self.importWizard.progressBar.setMaximum(len(self.importSource))
+            for file in self.importSource:
+                if self.stopImportFlag:
                     return
                 file_name = os.path.split(file)[1]
                 # Get the song title
                 self.title = file_name.rpartition(u'.')[0]
-                songData = open(file, 'rb')
-                if songData.read(19) != u'WoW File\nSong Words':
-                    self.log_error(file)
+                song_data = open(file, 'rb')
+                if song_data.read(19) != u'WoW File\nSong Words':
+                    self.logError(file)
                     continue
                 # Seek to byte which stores number of blocks in the song
-                songData.seek(56)
-                no_of_blocks = ord(songData.read(1))
+                song_data.seek(56)
+                no_of_blocks = ord(song_data.read(1))
                 # Seek to the beging of the first block
-                songData.seek(82)
+                song_data.seek(82)
                 for block in range(no_of_blocks):
-                    self.lines_to_read = ord(songData.read(1))
+                    self.linesToRead = ord(song_data.read(1))
                     # Skip 3 nulls to the beginnig of the 1st line
-                    songData.seek(3, os.SEEK_CUR)
+                    song_data.seek(3, os.SEEK_CUR)
                     block_text = u''
-                    while self.lines_to_read:
-                        self.line_text = unicode(
-                            songData.read(ord(songData.read(1))), u'cp1252')
-                        songData.seek(1, os.SEEK_CUR)
+                    while self.linesToRead:
+                        self.lineText = unicode(
+                            song_data.read(ord(song_data.read(1))), u'cp1252')
+                        song_data.seek(1, os.SEEK_CUR)
                         if block_text:
                             block_text += u'\n'
-                        block_text += self.line_text
-                        self.lines_to_read -= 1
-                    block_type = BLOCK_TYPES[ord(songData.read(1))]
+                        block_text += self.lineText
+                        self.linesToRead -= 1
+                    block_type = BLOCK_TYPES[ord(song_data.read(1))]
                     # Skip 3 nulls at the end of the block
-                    songData.seek(3, os.SEEK_CUR)
+                    song_data.seek(3, os.SEEK_CUR)
                     # Blocks are seperated by 2 bytes, skip them, but not if
                     # this is the last block!
                     if block + 1 < no_of_blocks:
-                        songData.seek(2, os.SEEK_CUR)
-                    self.add_verse(block_text, block_type)
+                        song_data.seek(2, os.SEEK_CUR)
+                    self.addVerse(block_text, block_type)
                 # Now to extract the author
-                author_length = ord(songData.read(1))
+                author_length = ord(song_data.read(1))
                 if author_length:
-                    self.parse_author(
-                        unicode(songData.read(author_length), u'cp1252'))
+                    self.parseAuthor(
+                        unicode(song_data.read(author_length), u'cp1252'))
                 # Finally the copyright
-                copyright_length = ord(songData.read(1))
+                copyright_length = ord(song_data.read(1))
                 if copyright_length:
-                    self.add_copyright(unicode(
-                        songData.read(copyright_length), u'cp1252'))
-                songData.close()
+                    self.addCopyright(unicode(
+                        song_data.read(copyright_length), u'cp1252'))
+                song_data.close()
                 if not self.finish():
-                    self.log_error(file)
+                    self.logError(file)

=== modified file 'openlp/plugins/songs/songsplugin.py'
--- openlp/plugins/songs/songsplugin.py	2011-08-25 09:22:48 +0000
+++ openlp/plugins/songs/songsplugin.py	2011-09-12 20:09:26 +0000
@@ -196,7 +196,7 @@
     def importSongs(self, format, **kwargs):
         class_ = SongFormat.get_class(format)
         importer = class_(self.manager, **kwargs)
-        importer.register(self.mediaItem.import_wizard)
+        importer.register(self.mediaItem.importWizard)
         return importer
 
     def setPluginTextStrings(self):
@@ -252,7 +252,7 @@
             progress.setValue(idx)
             Receiver.send_message(u'openlp_process_events')
             importer = OpenLPSongImport(self.manager, filename=db)
-            importer.do_import()
+            importer.doImport()
         progress.setValue(len(song_dbs))
         self.mediaItem.onSearchTextButtonClick()
 


Follow ups