← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~orangeshirt/openlp/bibles into lp:openlp

 

Armin Köhler has proposed merging lp:~orangeshirt/openlp/bibles into lp:openlp.

Requested reviews:
  Tim Bentley (trb143)
  Raoul Snyman (raoul-snyman)

For more details, see:
https://code.launchpad.net/~orangeshirt/openlp/bibles/+merge/59116

Please review and before merging all english strings needs an extra view ;-)

changed the behavior while importing bibles, in special webbibles they are now importing all there books while registering
Changed the local bible database (drop table "testament" and add a row book_reference_id in table "book")
moved csv files into a extended httpbooks.sqlite database - renamed to bibles_resources.sqlite
add two Dialog Windows which could pop up while importing, if the language or a book name is unknown
add a bible upgradewizard to upgrade older bible database versions
adapt many other things please look at the commit messeges

Bugs that should be fixed with that changes:
https://bugs.launchpad.net/openlp/+bug/609356
https://bugs.launchpad.net/openlp/+bug/722458
https://bugs.launchpad.net/openlp/+bug/706207
-- 
https://code.launchpad.net/~orangeshirt/openlp/bibles/+merge/59116
Your team OpenLP Core is subscribed to branch lp:openlp.
=== modified file 'openlp/core/resources.py'
--- openlp/core/resources.py	2011-03-24 19:04:02 +0000
+++ openlp/core/resources.py	2011-04-26 18:58:23 +0000
@@ -13246,6 +13246,56 @@
 \x7d\x05\x51\x09\xe2\xbe\xfe\x09\xa2\x12\x44\x25\x38\xdd\x96\xe5\
 \x3a\xcf\xd3\x74\x19\xc7\x1c\xed\x7b\x03\x2c\xc0\x04\x0b\x8e\x16\
 \xcd\xfc\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
+\x00\x00\x02\xfa\
+\x89\
+\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
+\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff\x61\
+\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\
+\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x01\xbb\x00\x00\x01\xbb\
+\x01\x3a\xec\xe3\xe2\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\
+\x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\
+\x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x02\x77\x49\x44\
+\x41\x54\x38\x8d\x8d\x51\x5d\x48\x53\x61\x18\x7e\xbe\x1d\x27\xc5\
+\x38\xb2\xf2\x0f\xe7\xdc\xa6\xce\x99\x90\x08\x5e\x14\x87\x4c\xdc\
+\xa0\xa0\x2e\x02\x2f\x0a\x4f\x21\x11\xb4\xba\x0a\x8e\x81\x5d\x19\
+\x84\x79\x37\x08\xaa\x0b\x85\xf0\xa2\xc2\x20\xc8\x9b\xa8\x0c\xbb\
+\x31\xc1\x18\xd1\x4d\x08\x05\x2d\x2d\x37\x9b\xba\xb9\xb5\xce\xce\
+\xe6\x99\x9e\x73\xde\x2e\xdc\x16\x53\x09\x1f\x78\xf9\xf8\xbe\xef\
+\x79\xde\x9f\xe7\x65\x44\x84\x9d\x60\x8c\x31\x00\x0d\x00\x3c\xf9\
+\xa7\x6f\x00\x22\xb4\x17\x99\x88\x76\x05\x80\xd6\x40\x20\x30\x21\
+\xcb\x72\x42\x96\xe5\x44\x20\x10\x98\x00\xd0\xba\x27\x77\x0f\xb1\
+\x45\x14\xc5\x61\xc3\xd0\x75\xe5\xf7\x42\x26\x9b\x5a\xcc\x1a\x86\
+\xa1\x8b\xa2\x38\x0c\xc0\xf2\xdf\x04\x79\x08\xb1\x68\x68\x55\xcb\
+\x46\x48\x59\x1c\x25\xe5\xc7\x38\x69\x1b\x2b\x94\x58\x0b\xad\x03\
+\x10\x76\x76\x6d\xda\x31\x11\x2f\x49\x92\x58\x5d\xe7\xae\x55\x57\
+\x5e\x42\x57\x57\xa1\xab\x51\xe4\xd6\xa6\x70\xb8\xc6\x5d\x29\x49\
+\x92\x08\x80\x2f\xf1\xab\x50\x99\x31\x06\xab\xd5\xda\x3d\xff\xf9\
+\xe3\xd3\x1a\xfe\x8f\x43\x59\xb8\x8f\xf1\x37\x07\xc1\x71\x1c\xae\
+\x9c\xd1\x60\x69\xbc\x86\x84\xc2\x2f\xdb\x1c\x6d\x7d\x00\xe6\x8a\
+\x1d\x17\x5a\x31\x9b\xcd\xfc\xd0\xd0\xd0\x28\x11\x51\x6c\xd6\x47\
+\x2b\xd3\xad\xe4\xf5\x7a\xa9\xab\xab\x8b\xa2\x53\x4e\x8a\xcd\x7a\
+\x89\x88\x48\x92\xa4\x07\x00\xf8\x12\x0f\x00\xc0\x6e\xb7\xf7\x44\
+\x97\xbf\x2f\xe7\x12\x1f\x28\x32\x09\x8a\x4c\x82\x5c\x2e\x17\xb9\
+\x5c\xae\xe2\x5d\x8d\xcf\x50\x34\xfc\xe5\x17\x80\x13\x85\xe2\x26\
+\x00\xe8\xed\xed\xad\xf4\xfb\xfd\x7d\x75\xf5\xcd\xf5\xe9\xd0\x3d\
+\x80\x71\xdb\x86\xf0\x3c\x78\xfe\xdf\xc8\xf2\xd7\x3b\xa8\x6b\x68\
+\xb3\x0d\x0c\x0c\x5c\x28\x78\x61\x02\x60\xc9\x64\x32\xc7\xaf\xfb\
+\xfb\xcf\x6d\x26\x83\x50\x57\x5f\x03\xa4\x03\x00\x3a\x9b\x15\x74\
+\x36\x2b\xc5\x04\xb9\xf8\x0c\x72\xeb\xef\x71\xeb\xe6\xd5\xf3\x00\
+\xda\x19\x63\xe0\x04\x41\x70\x57\x54\x54\xf8\x4f\x9d\x3e\x7b\x32\
+\xf9\xe9\x32\x34\x25\x54\x14\xf8\x3a\x52\xf0\x75\xa4\x4a\xd6\xa4\
+\x67\x7f\xa2\xb6\x7d\x90\x97\x65\x39\x13\x0c\x06\xe7\x98\xc7\xe3\
+\xf1\xbd\x9b\x7e\xfb\xa8\xd6\x12\x6e\x8a\xcf\xf6\x94\x90\x6f\xdc\
+\xdd\x3e\x1f\xde\x2e\xdd\x75\x75\xf7\x0c\xe2\xd9\xfa\xa5\x06\x67\
+\xcb\x45\x53\x55\x55\xd5\x51\x87\xb3\xb1\x29\x15\x7e\x95\xc5\x3e\
+\xa1\x84\x9f\xeb\x76\x87\xdb\x29\x08\xc2\xb1\x32\x55\x55\x73\x86\
+\x61\x68\x16\xf7\xe0\x96\x5a\x7e\x48\x2d\xe7\xb6\x0e\x14\x88\x8f\
+\x9f\xed\x16\x6f\x6a\xe6\x8d\x32\xdb\x25\x95\x88\xac\x86\x61\x68\
+\x00\xd0\x32\x32\x32\xf2\x24\x95\x4a\xc5\x68\x9f\x48\xa7\xd3\xc9\
+\xb1\xb1\xb1\x17\x00\x8e\x30\x00\x0c\x80\x0d\x40\x1b\x80\x1a\x00\
+\xe5\x00\xcc\x00\xca\x00\x70\xf9\x7f\x02\xa0\xe5\x63\x0b\x40\x12\
+\xc0\x3c\x80\xa5\xbf\x0f\xbe\x92\x25\xee\x27\x61\x5e\x00\x00\x00\
+\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
 \x00\x00\x02\xa3\
 \x89\
 \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
@@ -81685,6 +81735,11 @@
 \x00\x62\
 \x00\x69\x00\x62\x00\x6c\x00\x65\x00\x73\x00\x5f\x00\x73\x00\x65\x00\x61\x00\x72\x00\x63\x00\x68\x00\x5f\x00\x74\x00\x65\x00\x78\
 \x00\x74\x00\x2e\x00\x70\x00\x6e\x00\x67\
+\x00\x18\
+\x02\x0c\xd3\x27\
+\x00\x62\
+\x00\x69\x00\x62\x00\x6c\x00\x65\x00\x73\x00\x5f\x00\x75\x00\x70\x00\x67\x00\x72\x00\x61\x00\x64\x00\x65\x00\x5f\x00\x61\x00\x6c\
+\x00\x65\x00\x72\x00\x74\x00\x2e\x00\x70\x00\x6e\x00\x67\
 \x00\x0f\
 \x08\xfd\x86\xa7\
 \x00\x73\
@@ -82091,12 +82146,12 @@
 
 qt_resource_struct = "\
 \x00\x00\x00\x00\x00\x02\x00\x00\x00\x10\x00\x00\x00\x01\
-\x00\x00\x00\x98\x00\x02\x00\x00\x00\x06\x00\x00\x00\x79\
-\x00\x00\x00\x3a\x00\x02\x00\x00\x00\x04\x00\x00\x00\x75\
-\x00\x00\x01\x06\x00\x02\x00\x00\x00\x03\x00\x00\x00\x72\
-\x00\x00\x00\x5e\x00\x02\x00\x00\x00\x14\x00\x00\x00\x5e\
-\x00\x00\x00\x4e\x00\x02\x00\x00\x00\x02\x00\x00\x00\x5c\
-\x00\x00\x00\xe2\x00\x02\x00\x00\x00\x02\x00\x00\x00\x5a\
+\x00\x00\x00\x98\x00\x02\x00\x00\x00\x06\x00\x00\x00\x7a\
+\x00\x00\x00\x3a\x00\x02\x00\x00\x00\x04\x00\x00\x00\x76\
+\x00\x00\x01\x06\x00\x02\x00\x00\x00\x03\x00\x00\x00\x73\
+\x00\x00\x00\x5e\x00\x02\x00\x00\x00\x14\x00\x00\x00\x5f\
+\x00\x00\x00\x4e\x00\x02\x00\x00\x00\x02\x00\x00\x00\x5d\
+\x00\x00\x00\xe2\x00\x02\x00\x00\x00\x03\x00\x00\x00\x5a\
 \x00\x00\x00\x84\x00\x02\x00\x00\x00\x09\x00\x00\x00\x51\
 \x00\x00\x00\x14\x00\x02\x00\x00\x00\x0b\x00\x00\x00\x46\
 \x00\x00\x00\xa6\x00\x02\x00\x00\x00\x03\x00\x00\x00\x43\
@@ -82107,41 +82162,41 @@
 \x00\x00\x00\x26\x00\x02\x00\x00\x00\x01\x00\x00\x00\x25\
 \x00\x00\x00\x00\x00\x02\x00\x00\x00\x0f\x00\x00\x00\x16\
 \x00\x00\x00\xb8\x00\x02\x00\x00\x00\x05\x00\x00\x00\x11\
-\x00\x00\x07\x82\x00\x00\x00\x00\x00\x01\x00\x0d\xce\x84\
-\x00\x00\x06\xc0\x00\x00\x00\x00\x00\x01\x00\x03\x4a\xfc\
-\x00\x00\x07\x22\x00\x00\x00\x00\x00\x01\x00\x08\x8c\xc0\
-\x00\x00\x07\x50\x00\x00\x00\x00\x00\x01\x00\x0b\x2d\xa2\
-\x00\x00\x06\xf2\x00\x00\x00\x00\x00\x01\x00\x05\xeb\xde\
-\x00\x00\x11\xfe\x00\x00\x00\x00\x00\x01\x00\x13\xb3\x86\
-\x00\x00\x12\x6e\x00\x00\x00\x00\x00\x01\x00\x13\xba\xd1\
-\x00\x00\x11\xae\x00\x00\x00\x00\x00\x01\x00\x13\xae\x2a\
-\x00\x00\x13\x4c\x00\x00\x00\x00\x00\x01\x00\x13\xcd\x4f\
-\x00\x00\x12\xce\x00\x00\x00\x00\x00\x01\x00\x13\xc2\xe7\
-\x00\x00\x11\x56\x00\x00\x00\x00\x00\x01\x00\x13\xa6\xf3\
-\x00\x00\x12\x96\x00\x00\x00\x00\x00\x01\x00\x13\xbe\x45\
-\x00\x00\x11\x80\x00\x00\x00\x00\x00\x01\x00\x13\xa9\x91\
-\x00\x00\x13\x78\x00\x00\x00\x00\x00\x01\x00\x13\xd0\x82\
-\x00\x00\x13\x22\x00\x00\x00\x00\x00\x01\x00\x13\xca\xd7\
-\x00\x00\x11\xd4\x00\x00\x00\x00\x00\x01\x00\x13\xb1\x04\
-\x00\x00\x13\x9e\x00\x00\x00\x00\x00\x01\x00\x13\xd3\x56\
-\x00\x00\x12\xf6\x00\x00\x00\x00\x00\x01\x00\x13\xc6\x2c\
-\x00\x00\x12\x4a\x00\x00\x00\x00\x00\x01\x00\x13\xb7\xd4\
-\x00\x00\x12\x24\x00\x00\x00\x00\x00\x01\x00\x13\xb5\xbd\
-\x00\x00\x0f\x6c\x00\x00\x00\x00\x00\x01\x00\x13\x89\xcd\
-\x00\x00\x05\xe4\x00\x00\x00\x00\x00\x01\x00\x03\x3d\xfb\
-\x00\x00\x06\x64\x00\x00\x00\x00\x00\x01\x00\x03\x44\xc1\
-\x00\x00\x05\x68\x00\x00\x00\x00\x00\x01\x00\x03\x36\xf7\
-\x00\x00\x06\x0c\x00\x00\x00\x00\x00\x01\x00\x03\x40\x9b\
-\x00\x00\x06\x8e\x00\x00\x00\x00\x00\x01\x00\x03\x47\x8c\
-\x00\x00\x05\xb2\x00\x00\x00\x00\x00\x01\x00\x03\x3c\x11\
-\x00\x00\x05\x8c\x00\x00\x00\x00\x00\x01\x00\x03\x39\x9e\
-\x00\x00\x06\x42\x00\x00\x00\x00\x00\x01\x00\x03\x42\x1d\
+\x00\x00\x07\xb8\x00\x00\x00\x00\x00\x01\x00\x0d\xd1\x82\
+\x00\x00\x06\xf6\x00\x00\x00\x00\x00\x01\x00\x03\x4d\xfa\
+\x00\x00\x07\x58\x00\x00\x00\x00\x00\x01\x00\x08\x8f\xbe\
+\x00\x00\x07\x86\x00\x00\x00\x00\x00\x01\x00\x0b\x30\xa0\
+\x00\x00\x07\x28\x00\x00\x00\x00\x00\x01\x00\x05\xee\xdc\
+\x00\x00\x12\x34\x00\x00\x00\x00\x00\x01\x00\x13\xb6\x84\
+\x00\x00\x12\xa4\x00\x00\x00\x00\x00\x01\x00\x13\xbd\xcf\
+\x00\x00\x11\xe4\x00\x00\x00\x00\x00\x01\x00\x13\xb1\x28\
+\x00\x00\x13\x82\x00\x00\x00\x00\x00\x01\x00\x13\xd0\x4d\
+\x00\x00\x13\x04\x00\x00\x00\x00\x00\x01\x00\x13\xc5\xe5\
+\x00\x00\x11\x8c\x00\x00\x00\x00\x00\x01\x00\x13\xa9\xf1\
+\x00\x00\x12\xcc\x00\x00\x00\x00\x00\x01\x00\x13\xc1\x43\
+\x00\x00\x11\xb6\x00\x00\x00\x00\x00\x01\x00\x13\xac\x8f\
+\x00\x00\x13\xae\x00\x00\x00\x00\x00\x01\x00\x13\xd3\x80\
+\x00\x00\x13\x58\x00\x00\x00\x00\x00\x01\x00\x13\xcd\xd5\
+\x00\x00\x12\x0a\x00\x00\x00\x00\x00\x01\x00\x13\xb4\x02\
+\x00\x00\x13\xd4\x00\x00\x00\x00\x00\x01\x00\x13\xd6\x54\
+\x00\x00\x13\x2c\x00\x00\x00\x00\x00\x01\x00\x13\xc9\x2a\
+\x00\x00\x12\x80\x00\x00\x00\x00\x00\x01\x00\x13\xba\xd2\
+\x00\x00\x12\x5a\x00\x00\x00\x00\x00\x01\x00\x13\xb8\xbb\
+\x00\x00\x0f\xa2\x00\x00\x00\x00\x00\x01\x00\x13\x8c\xcb\
+\x00\x00\x06\x1a\x00\x00\x00\x00\x00\x01\x00\x03\x40\xf9\
+\x00\x00\x06\x9a\x00\x00\x00\x00\x00\x01\x00\x03\x47\xbf\
+\x00\x00\x05\x9e\x00\x00\x00\x00\x00\x01\x00\x03\x39\xf5\
+\x00\x00\x06\x42\x00\x00\x00\x00\x00\x01\x00\x03\x43\x99\
+\x00\x00\x06\xc4\x00\x00\x00\x00\x00\x01\x00\x03\x4a\x8a\
+\x00\x00\x05\xe8\x00\x00\x00\x00\x00\x01\x00\x03\x3f\x0f\
+\x00\x00\x05\xc2\x00\x00\x00\x00\x00\x01\x00\x03\x3c\x9c\
+\x00\x00\x06\x78\x00\x00\x00\x00\x00\x01\x00\x03\x45\x1b\
 \x00\x00\x01\x30\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
 \x00\x00\x01\x96\x00\x00\x00\x00\x00\x01\x00\x00\x05\xe6\
 \x00\x00\x01\x62\x00\x00\x00\x00\x00\x01\x00\x00\x02\xfe\
-\x00\x00\x0a\xba\x00\x00\x00\x00\x00\x01\x00\x11\xdd\x9d\
-\x00\x00\x0a\xea\x00\x00\x00\x00\x00\x01\x00\x12\x4c\xe2\
-\x00\x00\x0b\x0a\x00\x00\x00\x00\x00\x01\x00\x12\x53\x93\
+\x00\x00\x0a\xf0\x00\x00\x00\x00\x00\x01\x00\x11\xe0\x9b\
+\x00\x00\x0b\x20\x00\x00\x00\x00\x00\x01\x00\x12\x4f\xe0\
+\x00\x00\x0b\x40\x00\x00\x00\x00\x00\x01\x00\x12\x56\x91\
 \x00\x00\x02\x92\x00\x00\x00\x00\x00\x01\x00\x03\x02\x0d\
 \x00\x00\x02\x38\x00\x00\x00\x00\x00\x01\x00\x02\xfd\x0c\
 \x00\x00\x04\xb0\x00\x00\x00\x00\x00\x01\x00\x03\x27\x1c\
@@ -82157,66 +82212,67 @@
 \x00\x00\x03\x68\x00\x00\x00\x00\x00\x01\x00\x03\x0d\x51\
 \x00\x00\x04\x52\x00\x00\x00\x00\x00\x01\x00\x03\x20\xb7\
 \x00\x00\x03\x32\x00\x00\x00\x00\x00\x01\x00\x03\x0a\xa1\
-\x00\x00\x07\xd8\x00\x00\x00\x00\x00\x01\x00\x10\x72\x04\
-\x00\x00\x07\xf8\x00\x00\x00\x00\x00\x01\x00\x10\x75\xe1\
-\x00\x00\x07\xb2\x00\x00\x00\x00\x00\x01\x00\x10\x6f\x66\
-\x00\x00\x10\xd2\x00\x00\x00\x00\x00\x01\x00\x13\xa0\x36\
-\x00\x00\x11\x2c\x00\x00\x00\x00\x00\x01\x00\x13\xa4\xef\
-\x00\x00\x0f\xb8\x00\x00\x00\x00\x00\x01\x00\x13\x8e\xa0\
-\x00\x00\x10\x44\x00\x00\x00\x00\x00\x01\x00\x13\x95\x2e\
-\x00\x00\x10\xae\x00\x00\x00\x00\x00\x01\x00\x13\x9d\x03\
-\x00\x00\x10\x0e\x00\x00\x00\x00\x00\x01\x00\x13\x93\x35\
-\x00\x00\x10\x68\x00\x00\x00\x00\x00\x01\x00\x13\x97\xbf\
-\x00\x00\x10\x8a\x00\x00\x00\x00\x00\x01\x00\x13\x99\xd2\
-\x00\x00\x11\x08\x00\x00\x00\x00\x00\x01\x00\x13\xa2\x1e\
-\x00\x00\x0f\x90\x00\x00\x00\x00\x00\x01\x00\x13\x8b\xe4\
-\x00\x00\x0f\xec\x00\x00\x00\x00\x00\x01\x00\x13\x90\x97\
-\x00\x00\x0a\x42\x00\x00\x00\x00\x00\x01\x00\x11\xd7\x2b\
-\x00\x00\x09\xc6\x00\x00\x00\x00\x00\x01\x00\x11\xcd\xd0\
-\x00\x00\x09\x6a\x00\x00\x00\x00\x00\x01\x00\x11\xc8\x0e\
-\x00\x00\x09\xf4\x00\x00\x00\x00\x00\x01\x00\x11\xd1\x86\
-\x00\x00\x09\x42\x00\x00\x00\x00\x00\x01\x00\x11\xc5\x10\
-\x00\x00\x09\x90\x00\x00\x00\x00\x00\x01\x00\x11\xcb\xa5\
-\x00\x00\x0a\x1c\x00\x00\x00\x00\x00\x01\x00\x11\xd4\xc8\
-\x00\x00\x0a\x92\x00\x00\x00\x00\x00\x01\x00\x11\xdb\x97\
-\x00\x00\x0a\x6a\x00\x00\x00\x00\x00\x01\x00\x11\xd9\x7d\
+\x00\x00\x08\x0e\x00\x00\x00\x00\x00\x01\x00\x10\x75\x02\
+\x00\x00\x08\x2e\x00\x00\x00\x00\x00\x01\x00\x10\x78\xdf\
+\x00\x00\x07\xe8\x00\x00\x00\x00\x00\x01\x00\x10\x72\x64\
+\x00\x00\x11\x08\x00\x00\x00\x00\x00\x01\x00\x13\xa3\x34\
+\x00\x00\x11\x62\x00\x00\x00\x00\x00\x01\x00\x13\xa7\xed\
+\x00\x00\x0f\xee\x00\x00\x00\x00\x00\x01\x00\x13\x91\x9e\
+\x00\x00\x10\x7a\x00\x00\x00\x00\x00\x01\x00\x13\x98\x2c\
+\x00\x00\x10\xe4\x00\x00\x00\x00\x00\x01\x00\x13\xa0\x01\
+\x00\x00\x10\x44\x00\x00\x00\x00\x00\x01\x00\x13\x96\x33\
+\x00\x00\x10\x9e\x00\x00\x00\x00\x00\x01\x00\x13\x9a\xbd\
+\x00\x00\x10\xc0\x00\x00\x00\x00\x00\x01\x00\x13\x9c\xd0\
+\x00\x00\x11\x3e\x00\x00\x00\x00\x00\x01\x00\x13\xa5\x1c\
+\x00\x00\x0f\xc6\x00\x00\x00\x00\x00\x01\x00\x13\x8e\xe2\
+\x00\x00\x10\x22\x00\x00\x00\x00\x00\x01\x00\x13\x93\x95\
+\x00\x00\x0a\x78\x00\x00\x00\x00\x00\x01\x00\x11\xda\x29\
+\x00\x00\x09\xfc\x00\x00\x00\x00\x00\x01\x00\x11\xd0\xce\
+\x00\x00\x09\xa0\x00\x00\x00\x00\x00\x01\x00\x11\xcb\x0c\
+\x00\x00\x0a\x2a\x00\x00\x00\x00\x00\x01\x00\x11\xd4\x84\
+\x00\x00\x09\x78\x00\x00\x00\x00\x00\x01\x00\x11\xc8\x0e\
+\x00\x00\x09\xc6\x00\x00\x00\x00\x00\x01\x00\x11\xce\xa3\
+\x00\x00\x0a\x52\x00\x00\x00\x00\x00\x01\x00\x11\xd7\xc6\
+\x00\x00\x0a\xc8\x00\x00\x00\x00\x00\x01\x00\x11\xde\x95\
+\x00\x00\x0a\xa0\x00\x00\x00\x00\x00\x01\x00\x11\xdc\x7b\
+\x00\x00\x05\x68\x00\x00\x00\x00\x00\x01\x00\x03\x36\xf7\
 \x00\x00\x04\xfa\x00\x00\x00\x00\x00\x01\x00\x03\x2d\xb1\
 \x00\x00\x05\x36\x00\x00\x00\x00\x00\x01\x00\x03\x35\xa4\
-\x00\x00\x0e\x7a\x00\x00\x00\x00\x00\x01\x00\x13\x79\x21\
-\x00\x00\x0e\x9e\x00\x00\x00\x00\x00\x01\x00\x13\x7c\x1f\
-\x00\x00\x0b\x6e\x00\x00\x00\x00\x00\x01\x00\x13\x39\x56\
-\x00\x00\x0c\x54\x00\x00\x00\x00\x00\x01\x00\x13\x4a\x4a\
-\x00\x00\x0e\x5a\x00\x00\x00\x00\x00\x01\x00\x13\x75\x2e\
-\x00\x00\x0e\x28\x00\x00\x00\x00\x00\x01\x00\x13\x6e\x18\
-\x00\x00\x0d\x0e\x00\x00\x00\x00\x00\x01\x00\x13\x53\x18\
-\x00\x00\x0d\xae\x00\x00\x00\x00\x00\x01\x00\x13\x65\xd7\
-\x00\x00\x0d\xd8\x00\x00\x00\x00\x00\x01\x00\x13\x68\x0c\
-\x00\x00\x0c\xae\x00\x00\x00\x00\x00\x01\x00\x13\x4e\xfb\
-\x00\x00\x0c\xdc\x00\x00\x00\x00\x00\x01\x00\x13\x51\x7b\
-\x00\x00\x0b\xe2\x00\x00\x00\x00\x00\x01\x00\x13\x42\xfd\
-\x00\x00\x0c\x34\x00\x00\x00\x00\x00\x01\x00\x13\x47\x3e\
-\x00\x00\x0c\x7c\x00\x00\x00\x00\x00\x01\x00\x13\x4d\xa8\
-\x00\x00\x0d\x60\x00\x00\x00\x00\x00\x01\x00\x13\x59\x8d\
-\x00\x00\x0d\x34\x00\x00\x00\x00\x00\x01\x00\x13\x57\x2a\
-\x00\x00\x0d\xfa\x00\x00\x00\x00\x00\x01\x00\x13\x6c\x10\
-\x00\x00\x0b\x40\x00\x00\x00\x00\x00\x01\x00\x13\x32\x98\
-\x00\x00\x0b\x92\x00\x00\x00\x00\x00\x01\x00\x13\x3c\x42\
-\x00\x00\x0b\xbe\x00\x00\x00\x00\x00\x01\x00\x13\x3f\x84\
-\x00\x00\x0c\x12\x00\x00\x00\x00\x00\x01\x00\x13\x43\xf6\
-\x00\x00\x0d\x7e\x00\x00\x00\x00\x00\x01\x00\x13\x5c\x2f\
+\x00\x00\x0e\xb0\x00\x00\x00\x00\x00\x01\x00\x13\x7c\x1f\
+\x00\x00\x0e\xd4\x00\x00\x00\x00\x00\x01\x00\x13\x7f\x1d\
+\x00\x00\x0b\xa4\x00\x00\x00\x00\x00\x01\x00\x13\x3c\x54\
+\x00\x00\x0c\x8a\x00\x00\x00\x00\x00\x01\x00\x13\x4d\x48\
+\x00\x00\x0e\x90\x00\x00\x00\x00\x00\x01\x00\x13\x78\x2c\
+\x00\x00\x0e\x5e\x00\x00\x00\x00\x00\x01\x00\x13\x71\x16\
+\x00\x00\x0d\x44\x00\x00\x00\x00\x00\x01\x00\x13\x56\x16\
+\x00\x00\x0d\xe4\x00\x00\x00\x00\x00\x01\x00\x13\x68\xd5\
+\x00\x00\x0e\x0e\x00\x00\x00\x00\x00\x01\x00\x13\x6b\x0a\
+\x00\x00\x0c\xe4\x00\x00\x00\x00\x00\x01\x00\x13\x51\xf9\
+\x00\x00\x0d\x12\x00\x00\x00\x00\x00\x01\x00\x13\x54\x79\
+\x00\x00\x0c\x18\x00\x00\x00\x00\x00\x01\x00\x13\x45\xfb\
+\x00\x00\x0c\x6a\x00\x00\x00\x00\x00\x01\x00\x13\x4a\x3c\
+\x00\x00\x0c\xb2\x00\x00\x00\x00\x00\x01\x00\x13\x50\xa6\
+\x00\x00\x0d\x96\x00\x00\x00\x00\x00\x01\x00\x13\x5c\x8b\
+\x00\x00\x0d\x6a\x00\x00\x00\x00\x00\x01\x00\x13\x5a\x28\
+\x00\x00\x0e\x30\x00\x00\x00\x00\x00\x01\x00\x13\x6f\x0e\
+\x00\x00\x0b\x76\x00\x00\x00\x00\x00\x01\x00\x13\x35\x96\
+\x00\x00\x0b\xc8\x00\x00\x00\x00\x00\x01\x00\x13\x3f\x40\
+\x00\x00\x0b\xf4\x00\x00\x00\x00\x00\x01\x00\x13\x42\x82\
+\x00\x00\x0c\x48\x00\x00\x00\x00\x00\x01\x00\x13\x46\xf4\
+\x00\x00\x0d\xb4\x00\x00\x00\x00\x00\x01\x00\x13\x5f\x2d\
 \x00\x00\x01\xe4\x00\x00\x00\x00\x00\x01\x00\x00\x0c\xd8\
 \x00\x00\x01\xc2\x00\x00\x00\x00\x00\x01\x00\x00\x09\x05\
 \x00\x00\x02\x16\x00\x00\x00\x00\x00\x01\x00\x02\xfa\x36\
-\x00\x00\x0e\xbe\x00\x00\x00\x00\x00\x01\x00\x13\x7e\xa2\
-\x00\x00\x0f\x20\x00\x00\x00\x00\x00\x01\x00\x13\x85\x18\
-\x00\x00\x0e\xf2\x00\x00\x00\x00\x00\x01\x00\x13\x82\x04\
-\x00\x00\x0f\x48\x00\x00\x00\x00\x00\x01\x00\x13\x87\xb6\
-\x00\x00\x08\xaa\x00\x00\x00\x00\x00\x01\x00\x10\xb2\xef\
-\x00\x00\x08\x4a\x00\x00\x00\x00\x00\x01\x00\x10\x83\xaf\
-\x00\x00\x08\x1a\x00\x00\x00\x00\x00\x01\x00\x10\x79\x1b\
-\x00\x00\x08\x7a\x00\x00\x00\x00\x00\x01\x00\x10\x98\xe4\
-\x00\x00\x08\xda\x00\x00\x00\x00\x00\x01\x00\x10\xb7\x0c\
-\x00\x00\x09\x0e\x00\x00\x00\x00\x00\x01\x00\x11\x7f\xa5\
+\x00\x00\x0e\xf4\x00\x00\x00\x00\x00\x01\x00\x13\x81\xa0\
+\x00\x00\x0f\x56\x00\x00\x00\x00\x00\x01\x00\x13\x88\x16\
+\x00\x00\x0f\x28\x00\x00\x00\x00\x00\x01\x00\x13\x85\x02\
+\x00\x00\x0f\x7e\x00\x00\x00\x00\x00\x01\x00\x13\x8a\xb4\
+\x00\x00\x08\xe0\x00\x00\x00\x00\x00\x01\x00\x10\xb5\xed\
+\x00\x00\x08\x80\x00\x00\x00\x00\x00\x01\x00\x10\x86\xad\
+\x00\x00\x08\x50\x00\x00\x00\x00\x00\x01\x00\x10\x7c\x19\
+\x00\x00\x08\xb0\x00\x00\x00\x00\x00\x01\x00\x10\x9b\xe2\
+\x00\x00\x09\x10\x00\x00\x00\x00\x00\x01\x00\x10\xba\x0a\
+\x00\x00\x09\x44\x00\x00\x00\x00\x00\x01\x00\x11\x82\xa3\
 "
 
 def qInitResources():

=== modified file 'openlp/plugins/bibles/bibleplugin.py'
--- openlp/plugins/bibles/bibleplugin.py	2011-04-15 21:43:59 +0000
+++ openlp/plugins/bibles/bibleplugin.py	2011-04-26 18:58:23 +0000
@@ -32,6 +32,7 @@
 from openlp.core.lib.ui import base_action, UiStrings
 from openlp.core.utils.actions import ActionList
 from openlp.plugins.bibles.lib import BibleManager, BiblesTab, BibleMediaItem
+from openlp.plugins.bibles.forms import BibleUpgradeForm
 
 log = logging.getLogger(__name__)
 
@@ -58,6 +59,7 @@
         #action_list.add_action(self.exportBibleItem, UiStrings().Export)
         # Set to invisible until we can export bibles
         self.exportBibleItem.setVisible(False)
+        self.toolsUpgradeItem.setVisible(True)
 
     def finalise(self):
         """
@@ -87,6 +89,39 @@
         export_menu.addAction(self.exportBibleItem)
         self.exportBibleItem.setVisible(False)
 
+    def addToolsMenuItem(self, tools_menu):
+        """
+        Give the bible plugin the opportunity to add items to the
+        **Tools** menu.
+
+        ``tools_menu``
+            The actual **Tools** menu item, so that your actions can
+            use it as their parent.
+        """
+        log.info(u'add tools menu')
+        self.toolsUpgradeItem = QtGui.QAction(tools_menu)
+        self.toolsUpgradeItem.setObjectName(u'toolsUpgradeItem')
+        self.toolsUpgradeItem.setText(
+            translate('BiblePlugin', '&Upgrade older bible databases'))
+        self.toolsUpgradeItem.setStatusTip(
+            translate('BiblePlugin', 'Upgrade the bible databases to addapt '
+            'the database scheme.'))
+        tools_menu.addAction(self.toolsUpgradeItem)
+        QtCore.QObject.connect(self.toolsUpgradeItem,
+            QtCore.SIGNAL(u'triggered()'), self.onToolsUpgradeItemTriggered)
+        self.toolsUpgradeItem.setVisible(False)
+
+    def onToolsUpgradeItemTriggered(self):
+        """
+        Upgrade older bible databases.
+        """
+        if not hasattr(self, u'upgrade_wizard'):
+            self.upgrade_wizard = BibleUpgradeForm(self.formparent, 
+                self.manager, self)
+        # If the import was not cancelled then reload.
+        if self.upgrade_wizard.exec_():
+            self.mediaItem.reloadBibles()
+
     def onBibleImportClick(self):
         if self.mediaItem:
             self.mediaItem.onImportClick()
@@ -146,4 +181,4 @@
             u'service': translate('BiblesPlugin',
                 'Add the selected Bible to the service')
         }
-        self.setPluginUiTextStrings(tooltips)
\ No newline at end of file
+        self.setPluginUiTextStrings(tooltips)

=== modified file 'openlp/plugins/bibles/forms/__init__.py'
--- openlp/plugins/bibles/forms/__init__.py	2011-03-24 19:04:02 +0000
+++ openlp/plugins/bibles/forms/__init__.py	2011-04-26 18:58:23 +0000
@@ -50,7 +50,10 @@
 them separate from the functionality, so that it is easier to recreate the GUI
 from the .ui files later if necessary.
 """
-
+from booknameform import BookNameForm
+from languageform import LanguageForm
 from bibleimportform import BibleImportForm
+from bibleupgradeform import BibleUpgradeForm
 
-__all__ = ['BibleImportForm']
+__all__ = [u'BookNameForm', u'LanguageForm', u'BibleImportForm', 
+    u'BibleUpgradeForm']

=== modified file 'openlp/plugins/bibles/forms/bibleimportform.py'
--- openlp/plugins/bibles/forms/bibleimportform.py	2011-04-15 21:43:59 +0000
+++ openlp/plugins/bibles/forms/bibleimportform.py	2011-04-26 18:58:23 +0000
@@ -30,6 +30,7 @@
 import logging
 import os
 import os.path
+import re
 
 from PyQt4 import QtCore, QtGui
 
@@ -39,6 +40,7 @@
 from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
 from openlp.core.utils import AppLocation, string_is_unicode
 from openlp.plugins.bibles.lib.manager import BibleFormat
+from openlp.plugins.bibles.lib.db import BiblesResourcesDB
 
 log = logging.getLogger(__name__)
 
@@ -123,9 +125,6 @@
         QtCore.QObject.connect(self.osisBrowseButton,
             QtCore.SIGNAL(u'clicked()'),
             self.onOsisBrowseButtonClicked)
-        QtCore.QObject.connect(self.csvTestamentsButton,
-            QtCore.SIGNAL(u'clicked()'),
-            self.onCsvTestamentsBrowseButtonClicked)
         QtCore.QObject.connect(self.csvBooksButton,
             QtCore.SIGNAL(u'clicked()'),
             self.onCsvBooksBrowseButtonClicked)
@@ -186,18 +185,6 @@
         self.csvLayout = QtGui.QFormLayout(self.csvWidget)
         self.csvLayout.setMargin(0)
         self.csvLayout.setObjectName(u'CsvLayout')
-        self.csvTestamentsLabel = QtGui.QLabel(self.csvWidget)
-        self.csvTestamentsLabel.setObjectName(u'CsvTestamentsLabel')
-        self.csvTestamentsLayout = QtGui.QHBoxLayout()
-        self.csvTestamentsLayout.setObjectName(u'CsvTestamentsLayout')
-        self.csvTestamentsEdit = QtGui.QLineEdit(self.csvWidget)
-        self.csvTestamentsEdit.setObjectName(u'CsvTestamentsEdit')
-        self.csvTestamentsLayout.addWidget(self.csvTestamentsEdit)
-        self.csvTestamentsButton = QtGui.QToolButton(self.csvWidget)
-        self.csvTestamentsButton.setIcon(self.openIcon)
-        self.csvTestamentsButton.setObjectName(u'CsvTestamentsButton')
-        self.csvTestamentsLayout.addWidget(self.csvTestamentsButton)
-        self.csvLayout.addRow(self.csvTestamentsLabel, self.csvTestamentsLayout)
         self.csvBooksLabel = QtGui.QLabel(self.csvWidget)
         self.csvBooksLabel.setObjectName(u'CsvBooksLabel')
         self.csvBooksLayout = QtGui.QHBoxLayout()
@@ -382,8 +369,6 @@
             translate('BiblesPlugin.ImportWizardForm', 'Bible file:'))
         self.osisFileLabel.setText(
             translate('BiblesPlugin.ImportWizardForm', 'Bible file:'))
-        self.csvTestamentsLabel.setText(
-            translate('BiblesPlugin.ImportWizardForm', 'Testaments file:'))
         self.csvBooksLabel.setText(
             translate('BiblesPlugin.ImportWizardForm', 'Books file:'))
         self.csvVersesLabel.setText(
@@ -434,7 +419,6 @@
         # Align all QFormLayouts towards each other.
         labelWidth = max(self.formatLabel.minimumSizeHint().width(),
             self.osisFileLabel.minimumSizeHint().width(),
-            self.csvTestamentsLabel.minimumSizeHint().width(),
             self.csvBooksLabel.minimumSizeHint().width(),
             self.csvVersesLabel.minimumSizeHint().width(),
             self.openSongFileLabel.minimumSizeHint().width(),
@@ -456,14 +440,6 @@
                     self.osisFileEdit.setFocus()
                     return False
             elif self.field(u'source_format').toInt()[0] == BibleFormat.CSV:
-                if not self.field(u'csv_testamentsfile').toString():
-                    answer = critical_error_message_box(UiStrings().NFSs,
-                        translate('BiblesPlugin.ImportWizardForm',
-                        'You have not specified a testaments file. Do you '
-                        'want to proceed with the import?'), question=True)
-                    if answer == QtGui.QMessageBox.No:
-                        self.csvTestamentsEdit.setFocus()
-                        return False
                 if not self.field(u'csv_booksfile').toString():
                     critical_error_message_box(UiStrings().NFSs,
                         translate('BiblesPlugin.ImportWizardForm',
@@ -496,6 +472,7 @@
             license_version = unicode(self.field(u'license_version').toString())
             license_copyright = \
                 unicode(self.field(u'license_copyright').toString())
+            path = AppLocation.get_section_data_path(u'bibles/bibles')
             if not license_version:
                 critical_error_message_box(UiStrings().EmptyField,
                     translate('BiblesPlugin.ImportWizardForm',
@@ -517,10 +494,32 @@
                     'a different Bible or first delete the existing one.'))
                 self.versionNameEdit.setFocus()
                 return False
+            elif os.path.exists(os.path.join(path, self.clean_filename(
+                license_version))):
+                critical_error_message_box(
+                    translate('BiblesPlugin.ImportWizardForm', 'Bible Exists'),
+                    translate('BiblesPlugin.ImportWizardForm',
+                    'This Bible already exists. Please import '
+                    'a different Bible or first delete the existing one.'))
+                self.versionNameEdit.setFocus()
+                return False
             return True
         if self.currentPage() == self.progressPage:
             return True
 
+    def clean_filename(self, old_filename):
+        """
+        Clean up the version name of the Bible and convert it into a valid
+        file name.
+
+        ``old_filename``
+            The "dirty" file name or version name.
+        """
+        if not isinstance(old_filename, unicode):
+            old_filename = unicode(old_filename, u'utf-8')
+        old_filename = re.sub(r'[^\w]+', u'_', old_filename).strip(u'_')
+        return old_filename + u'.sqlite'
+
     def onWebSourceComboBoxIndexChanged(self, index):
         """
         Setup the list of Bibles when you select a different source on the web
@@ -541,14 +540,6 @@
         self.getFileName(WizardStrings.OpenTypeFile % WizardStrings.OSIS,
             self.osisFileEdit)
 
-    def onCsvTestamentsBrowseButtonClicked(self):
-        """
-        Show the file open dialog for the testaments CSV file.
-        """
-        self.getFileName(WizardStrings.OpenTypeFile % WizardStrings.CSV,
-            self.csvTestamentsEdit, u'%s (*.csv)'
-            % translate('BiblesPlugin.ImportWizardForm', 'CSV File'))
-
     def onCsvBooksBrowseButtonClicked(self):
         """
         Show the file open dialog for the books CSV file.
@@ -587,8 +578,6 @@
         """
         self.selectPage.registerField(u'source_format', self.formatComboBox)
         self.selectPage.registerField(u'osis_location', self.osisFileEdit)
-        self.selectPage.registerField(
-            u'csv_testamentsfile', self.csvTestamentsEdit)
         self.selectPage.registerField(u'csv_booksfile', self.csvBooksEdit)
         self.selectPage.registerField(u'csv_versefile', self.csvVersesEdit)
         self.selectPage.registerField(u'opensong_file', self.openSongFileEdit)
@@ -617,7 +606,6 @@
         self.cancelButton.setVisible(True)
         self.setField(u'source_format', QtCore.QVariant(0))
         self.setField(u'osis_location', QtCore.QVariant(''))
-        self.setField(u'csv_testamentsfile', QtCore.QVariant(''))
         self.setField(u'csv_booksfile', QtCore.QVariant(''))
         self.setField(u'csv_versefile', QtCore.QVariant(''))
         self.setField(u'opensong_file', QtCore.QVariant(''))
@@ -644,46 +632,27 @@
         """
         Load the lists of Crosswalk, BibleGateway and Bibleserver bibles.
         """
-        filepath = AppLocation.get_directory(AppLocation.PluginsDir)
-        filepath = os.path.join(filepath, u'bibles', u'resources')
         # Load Crosswalk Bibles.
-        self.loadBibleResourceFile(
-            os.path.join(filepath, u'crosswalkbooks.csv'),
-            WebDownload.Crosswalk)
+        self.loadBibleResource(WebDownload.Crosswalk)
         # Load BibleGateway Bibles.
-        self.loadBibleResourceFile(os.path.join(filepath, u'biblegateway.csv'),
-            WebDownload.BibleGateway)
+        self.loadBibleResource(WebDownload.BibleGateway)
         # Load and Bibleserver Bibles.
-        self.loadBibleResourceFile(os.path.join(filepath, u'bibleserver.csv'),
-            WebDownload.Bibleserver)
+        self.loadBibleResource(WebDownload.Bibleserver)
 
-    def loadBibleResourceFile(self, file_path_name, download_type):
+    def loadBibleResource(self, download_type):
         """
-        Loads a web bible resource file.
-
-        ``file_path_name``
-            The file to load including the file's path.
+        Loads a web bible from bible_resources.sqlite.
 
         ``download_type``
-            The WebDownload type this file is for.
+            The WebDownload type e.g. bibleserver.
         """
         self.web_bible_list[download_type] = {}
-        books_file = None
-        try:
-            books_file = open(file_path_name, 'rb')
-            dialect = csv.Sniffer().sniff(books_file.read(1024))
-            books_file.seek(0)
-            books_reader = csv.reader(books_file, dialect)
-            for line in books_reader:
-                ver = string_is_unicode(line[0])
-                name = string_is_unicode(line[1])
-                self.web_bible_list[download_type][ver] = name.strip()
-        except IOError:
-            log.exception(u'%s resources missing' %
-                WebDownload.Names[download_type])
-        finally:
-            if books_file:
-                books_file.close()
+        bibles = BiblesResourcesDB.get_webbibles(
+            WebDownload.Names[download_type])
+        for bible in bibles:
+            ver = bible[u'name']
+            name = bible[u'abbreviation']
+            self.web_bible_list[download_type][ver] = name.strip()
 
     def preWizard(self):
         """
@@ -718,8 +687,7 @@
         elif bible_type == BibleFormat.CSV:
             # Import a CSV bible.
             importer = self.manager.import_bible(BibleFormat.CSV,
-                name=license_version, testamentsfile=unicode(
-                self.field(u'csv_testamentsfile').toString()),
+                name=license_version, 
                 booksfile=unicode(self.field(u'csv_booksfile').toString()),
                 versefile=unicode(self.field(u'csv_versefile').toString())
             )
@@ -765,4 +733,4 @@
             self.progressLabel.setText(translate(
                 'BiblesPlugin.ImportWizardForm', 'Your Bible import failed.'))
             del self.manager.db_cache[importer.name]
-            delete_database(self.plugin.settingsSection, importer.file)
\ No newline at end of file
+            delete_database(self.plugin.settingsSection, importer.file)

=== added file 'openlp/plugins/bibles/forms/bibleupgradeform.py'
--- openlp/plugins/bibles/forms/bibleupgradeform.py	1970-01-01 00:00:00 +0000
+++ openlp/plugins/bibles/forms/bibleupgradeform.py	2011-04-26 18:58:23 +0000
@@ -0,0 +1,699 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection                                      #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2011 Raoul Snyman                                        #
+# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael      #
+# Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler,        #
+# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout,      #
+# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund             #
+# --------------------------------------------------------------------------- #
+# This program is free software; you can redistribute it and/or modify it     #
+# under the terms of the GNU General Public License as published by the Free  #
+# Software Foundation; version 2 of the License.                              #
+#                                                                             #
+# This program is distributed in the hope that it will be useful, but WITHOUT #
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       #
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    #
+# more details.                                                               #
+#                                                                             #
+# You should have received a copy of the GNU General Public License along     #
+# with this program; if not, write to the Free Software Foundation, Inc., 59  #
+# Temple Place, Suite 330, Boston, MA 02111-1307 USA                          #
+###############################################################################
+"""
+The bible import functions for OpenLP
+"""
+import logging
+import os
+import os.path
+import re
+
+from PyQt4 import QtCore, QtGui
+
+from openlp.core.lib import Receiver, SettingsManager, translate
+from openlp.core.lib.db import delete_database
+from openlp.core.lib.ui import UiStrings, critical_error_message_box
+from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
+from openlp.core.utils import AppLocation, delete_file
+from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta, OldBibleDB,\
+    BiblesResourcesDB
+from openlp.plugins.bibles.lib.http import BSExtract, BGExtract, CWExtract
+
+log = logging.getLogger(__name__)
+
+
+class BibleUpgradeForm(OpenLPWizard):
+    """
+    This is the Bible Upgrade Wizard, which allows easy importing of Bibles
+    into OpenLP from older OpenLP2 database versions.
+    """
+    log.info(u'BibleUpgradeForm loaded')
+
+    def __init__(self, parent, manager, bibleplugin):
+        """
+        Instantiate the wizard, and run any extra setup we need to.
+
+        ``parent``
+            The QWidget-derived parent of the wizard.
+
+        ``manager``
+            The Bible manager.
+
+        ``bibleplugin``
+            The Bible plugin.
+        """
+        self.manager = manager
+        self.mediaItem = bibleplugin.mediaItem
+        self.suffix = u'.sqlite'
+        self.settingsSection = u'bibles/bibles'
+        self.oldsettingsSection = u'bibles'
+        self.oldpath = AppLocation.get_section_data_path(
+            self.oldsettingsSection)
+        self.newpath = AppLocation.get_section_data_path(
+            self.settingsSection)
+        self.files = SettingsManager.get_files(self.oldsettingsSection, 
+            self.suffix)
+        self.success = {}
+        self.newbibles = {}
+        self.maxBibles = len(self.files)
+        self.stop_import_flag = False
+        OpenLPWizard.__init__(self, parent, bibleplugin, u'bibleUpgradeWizard',
+            u':/wizards/wizard_importbible.bmp')
+
+    def setupUi(self, image):
+        """
+        Set up the UI for the bible wizard.
+        """
+        OpenLPWizard.setupUi(self, image)
+        QtCore.QObject.connect(Receiver.get_receiver(),
+            QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import)
+
+    def stop_import(self):
+        """
+        Stops the import of the Bible.
+        """
+        log.debug(u'Stopping import')
+        self.stop_import_flag = True
+
+    def clean_filename(self, old_filename):
+        """
+        Clean up the version name of the Bible and convert it into a valid
+        file name.
+
+        ``old_filename``
+            The "dirty" file name or version name.
+        """
+        if not isinstance(old_filename, unicode):
+            old_filename = unicode(old_filename, u'utf-8')
+        old_filename = re.sub(r'[^\w]+', u'_', old_filename).strip(u'_')
+        return old_filename + u'.sqlite'
+
+    def onCheckBoxIndexChanged(self, index):
+        '''
+        Show/ Hide warnings if CheckBox state has changed
+        '''
+        for number, filename in enumerate(self.files):
+            if not self.checkBox[number].checkState() == 2:
+                self.verticalWidget[number].hide()
+                self.formWidget[number].hide()
+            else:
+                if os.path.exists(os.path.join(self.newpath, filename)):
+                    self.verticalWidget[number].show()
+                    self.formWidget[number].show()
+
+    def reject(self):
+        """
+        Stop the wizard on cancel button, close button or ESC key.
+        """
+        log.debug(u'Wizard cancelled by user')
+        if self.currentPage() == self.progressPage:
+            Receiver.send_message(u'openlp_stop_wizard')
+            for bible in self.newbibles.itervalues():
+                delete_database(self.newpath, bible.clean_filename(
+                    bible.get_name())) 
+        self.done(QtGui.QDialog.Rejected)
+
+    def onCurrentIdChanged(self, pageId):
+        """
+        Perform necessary functions depending on which wizard page is active.
+        """
+        if self.page(pageId) == self.progressPage:
+            self.preWizard()
+            self.performWizard()
+            self.postWizard()
+        elif self.page(pageId) == self.selectPage and self.maxBibles == 0:
+            self.next()
+
+    def onFinishButton(self):
+        '''
+        Some cleanup while finishing
+        '''
+        if self.deleteCheckBox.checkState() == 2 or \
+            self.deleteAllCheckBox.checkState() == 2:
+            for number, filename in enumerate(self.files):
+                if self.deleteAllCheckBox.checkState() == 2 or \
+                    (self.checkBox[number].checkState() == 2 and \
+                    self.success[number] == True):
+                    delete_file(os.path.join(self.oldpath, filename))
+
+    def customInit(self):
+        """
+        Perform any custom initialisation for bible upgrading.
+        """
+        self.manager.set_process_dialog(self)
+        self.restart()
+
+    def customSignals(self):
+        """
+        Set up the signals used in the bible importer.
+        """
+        for number, filename in enumerate(self.files):
+            QtCore.QObject.connect(self.checkBox[number],
+                QtCore.SIGNAL(u'stateChanged(int)'),
+                self.onCheckBoxIndexChanged)
+        QtCore.QObject.connect(self.finishButton,
+            QtCore.SIGNAL(u'clicked()'), self.onFinishButton)
+
+    def addCustomPages(self):
+        """
+        Add the bible import specific wizard pages.
+        """
+        self.selectPage = QtGui.QWizardPage()
+        self.selectPage.setObjectName(u'SelectPage')
+        self.pageLayout = QtGui.QVBoxLayout(self.selectPage)
+        self.pageLayout.setObjectName(u'pageLayout')
+        self.scrollArea = QtGui.QScrollArea(self.selectPage)
+        self.scrollArea.setWidgetResizable(True)
+        self.scrollArea.setObjectName(u'scrollArea')
+        self.scrollArea.setHorizontalScrollBarPolicy(
+            QtCore.Qt.ScrollBarAlwaysOff)
+        self.scrollAreaContents = QtGui.QWidget(self.scrollArea)
+        self.scrollAreaContents.setObjectName(u'scrollAreaContents')
+        self.formLayout = QtGui.QVBoxLayout(self.scrollAreaContents)
+        self.formLayout.setSpacing(2)
+        self.formLayout.setObjectName(u'formLayout')
+        self.addScrollArea()
+        self.pageLayout.addWidget(self.scrollArea)
+        self.addPage(self.selectPage)
+
+    def addScrollArea(self):
+        """
+        Add the content to the scrollArea.
+        """
+        self.checkBox = {}
+        self.versionNameEdit = {}
+        self.versionNameLabel = {}
+        self.versionInfoLabel = {}
+        self.versionInfoPixmap = {}
+        self.verticalWidget = {}
+        self.horizontalLayout = {}
+        self.formWidget = {}
+        self.formLayoutAttention = {}
+        for number, filename in enumerate(self.files):
+            bible = OldBibleDB(self.mediaItem, path=self.oldpath, file=filename)
+            self.checkBox[number] = QtGui.QCheckBox(self.scrollAreaContents)
+            checkBoxName = u'checkBox['+unicode(number)+u']'
+            self.checkBox[number].setObjectName(checkBoxName)
+            self.checkBox[number].setText(bible.get_name())
+            self.checkBox[number].setCheckState(2)
+            self.formLayout.addWidget(self.checkBox[number])
+            self.verticalWidget[number] = QtGui.QWidget(self.scrollAreaContents)
+            verticalWidgetName = u'verticalWidget['+unicode(number)+u']'
+            self.verticalWidget[number].setObjectName(verticalWidgetName)
+            self.horizontalLayout[number] = QtGui.QHBoxLayout(
+                self.verticalWidget[number])
+            self.horizontalLayout[number].setContentsMargins(25, 0, 0, 0)
+            horizontalLayoutName = u'horizontalLayout['+unicode(number)+u']'
+            self.horizontalLayout[number].setObjectName(horizontalLayoutName)
+            self.versionInfoPixmap[number] = QtGui.QLabel(
+                self.verticalWidget[number])
+            versionInfoPixmapName = u'versionInfoPixmap['+unicode(number)+u']'
+            self.versionInfoPixmap[number].setObjectName(versionInfoPixmapName)
+            self.versionInfoPixmap[number].setPixmap(QtGui.QPixmap(
+                u':/bibles/bibles_upgrade_alert.png'))
+            self.versionInfoPixmap[number].setAlignment(QtCore.Qt.AlignRight)
+            self.horizontalLayout[number].addWidget(
+                self.versionInfoPixmap[number])
+            self.versionInfoLabel[number] = QtGui.QLabel(
+                self.verticalWidget[number])
+            versionInfoLabelName = u'versionInfoLabel['+unicode(number)+u']'
+            self.versionInfoLabel[number].setObjectName(versionInfoLabelName)
+            sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, 
+                QtGui.QSizePolicy.Preferred)
+            sizePolicy.setHorizontalStretch(0)
+            sizePolicy.setVerticalStretch(0)
+            sizePolicy.setHeightForWidth(
+                self.versionInfoLabel[number].sizePolicy().hasHeightForWidth())
+            self.versionInfoLabel[number].setSizePolicy(sizePolicy)
+            self.horizontalLayout[number].addWidget(
+                self.versionInfoLabel[number])
+            self.formLayout.addWidget(self.verticalWidget[number])
+            self.formWidget[number] = QtGui.QWidget(self.scrollAreaContents)
+            formWidgetName = u'formWidget['+unicode(number)+u']'
+            self.formWidget[number].setObjectName(formWidgetName)
+            self.formLayoutAttention[number] = QtGui.QFormLayout(
+                self.formWidget[number])
+            self.formLayoutAttention[number].setContentsMargins(25, 0, 0, 5)
+            formLayoutAttentionName = u'formLayoutAttention['+unicode(number)+\
+                u']'
+            self.formLayoutAttention[number].setObjectName(
+                formLayoutAttentionName)
+            self.versionNameLabel[number] = QtGui.QLabel(
+                self.formWidget[number])
+            self.versionNameLabel[number].setObjectName(u'VersionNameLabel')
+            self.formLayoutAttention[number].setWidget(0, 
+                QtGui.QFormLayout.LabelRole, self.versionNameLabel[number])
+            self.versionNameEdit[number] = QtGui.QLineEdit(
+                self.formWidget[number])
+            self.versionNameEdit[number].setObjectName(u'VersionNameEdit')
+            self.formLayoutAttention[number].setWidget(0, 
+                QtGui.QFormLayout.FieldRole, self.versionNameEdit[number])
+            self.versionNameEdit[number].setText(bible.get_name())
+            self.formLayout.addWidget(self.formWidget[number])
+        self.spacerItem = QtGui.QSpacerItem(20, 5, QtGui.QSizePolicy.Minimum,
+            QtGui.QSizePolicy.Expanding)
+        self.formLayout.addItem(self.spacerItem)
+        self.scrollArea.setWidget(self.scrollAreaContents)
+
+    def clearScrollArea(self):
+        """
+        Remove the content from the scrollArea.
+        """
+        for number, filename in enumerate(self.files):
+            self.formLayout.removeWidget(self.checkBox[number])
+            self.checkBox[number].setParent(None)
+            self.horizontalLayout[number].removeWidget(
+                self.versionInfoPixmap[number])
+            self.versionInfoPixmap[number].setParent(None)
+            self.horizontalLayout[number].removeWidget(
+                self.versionInfoLabel[number])
+            self.versionInfoLabel[number].setParent(None)
+            self.formLayout.removeWidget(self.verticalWidget[number])
+            self.verticalWidget[number].setParent(None)
+            self.formLayoutAttention[number].removeWidget(
+                self.versionNameLabel[number])
+            self.versionNameLabel[number].setParent(None)
+            self.formLayoutAttention[number].removeWidget(
+                self.versionNameEdit[number])
+            self.formLayoutAttention[number].deleteLater()
+            self.versionNameEdit[number].setParent(None)
+            self.formLayout.removeWidget(self.formWidget[number])
+            self.formWidget[number].setParent(None)
+        self.formLayout.removeItem(self.spacerItem)  
+
+    def addProgressPage(self):
+        """
+        Add the progress page for the wizard. This page informs the user how
+        the wizard is progressing with its task.
+        """
+        OpenLPWizard.addProgressPage(self)
+        self.progressLayout.setContentsMargins(48, 48, 48, 30)
+        self.progressLabelAfter = QtGui.QLabel(self.progressPage)
+        self.progressLabelAfter.setObjectName(u'progressLabelAfter')
+        self.progressLayout.addWidget(self.progressLabelAfter)
+        self.deleteCheckBox = QtGui.QCheckBox(self.progressPage)
+        self.deleteCheckBox.setObjectName(u'deleteCheckBox')
+        self.progressLayout.addWidget(self.deleteCheckBox)
+        self.deleteAllCheckBox = QtGui.QCheckBox(self.progressPage)
+        self.deleteAllCheckBox.setObjectName(u'deleteAllCheckBox')
+        self.progressLayout.addWidget(self.deleteAllCheckBox)
+
+    def retranslateUi(self):
+        """
+        Allow for localisation of the bible import wizard.
+        """
+        self.setWindowTitle(translate('BiblesPlugin.UpgradeWizardForm', 
+            'Bible Upgrade Wizard'))
+        self.titleLabel.setText(WizardStrings.HeaderStyle %
+            translate('OpenLP.Ui', 'Welcome to the Bible Upgrade Wizard'))
+        self.informationLabel.setText(
+            translate('BiblesPlugin.UpgradeWizardForm',
+            'This wizard will help you to upgrade your existing Bibles from a '
+            'prior version of OpenLP 2. Click the next button below to start '
+            'the process by selecting the bibles to upgrade.'))
+        self.selectPage.setTitle(
+            translate('BiblesPlugin.UpgradeWizardForm',
+            'Please choose'))
+        self.selectPage.setSubTitle(
+            translate('BiblesPlugin.UpgradeWizardForm',
+            'Please choose the bibles which should be upgraded'))
+        for number, bible in enumerate(self.files):
+            self.versionNameLabel[number].setText(
+                translate('BiblesPlugin.UpgradeWizardForm', 'Version name:'))
+            self.versionInfoLabel[number].setText(
+                translate('BiblesPlugin.UpgradeWizardForm', 'This '
+                'bible still exists. Please change the name or uncheck it.'))
+        self.progressPage.setTitle(WizardStrings.Importing)
+        self.progressPage.setSubTitle(
+            translate('BiblesPlugin.UpgradeWizardForm',
+            'Please wait while your Bibles are upgraded.'))
+        self.progressLabel.setText(WizardStrings.Ready)
+        self.progressBar.setFormat(u'%p%')
+        self.deleteCheckBox.setText(
+            translate('BiblesPlugin.UpgradeWizardForm', 'Delete old bible '
+            'database(s) from bibles which was upgraded\nsucessful right now'))
+        self.deleteAllCheckBox.setText(
+            translate('BiblesPlugin.UpgradeWizardForm', 'Delete all old bible '
+            'database(s) (including not upgraded bibles)'))
+        self.progressLabelAfter.setText(
+            translate('BiblesPlugin.UpgradeWizardForm', 'If OpenLP should '
+            'delete the old bible databases please choose:'))
+
+    def validateCurrentPage(self):
+        """
+        Validate the current page before moving on to the next page.
+        """
+        if self.currentPage() == self.welcomePage:
+            return True
+        elif self.currentPage() == self.selectPage:
+            for number, filename in enumerate(self.files):
+                if not self.checkBox[number].checkState() == 2:
+                    continue
+                version_name = unicode(self.versionNameEdit[number].text())
+                oldbible = OldBibleDB(self.mediaItem, path=self.oldpath, 
+                    file=filename)
+                oldname = oldbible.get_name()
+                if not version_name:
+                    critical_error_message_box(UiStrings().EmptyField,
+                        translate('BiblesPlugin.UpgradeWizardForm',
+                        'You need to specify a version name for your Bible.'))
+                    self.versionNameEdit[number].setFocus()
+                    return False
+                elif self.manager.exists(version_name):
+                    critical_error_message_box(
+                        translate('BiblesPlugin.UpgradeWizardForm', 
+                            'Bible Exists'),
+                        translate('BiblesPlugin.UpgradeWizardForm',
+                        'This Bible already exists. Please upgrade '
+                        'a different Bible, delete the existing one or '
+                        'uncheck.'))
+                    self.versionNameEdit[number].setFocus()
+                    return False
+                elif os.path.exists(os.path.join(self.newpath, filename)) and \
+                    version_name == oldname:
+                    critical_error_message_box(
+                        translate('BiblesPlugin.UpgradeWizardForm', 
+                            'Bible Exists'),
+                        translate('BiblesPlugin.UpgradeWizardForm',
+                        'This Bible already exists. Please upgrade '
+                        'a different Bible, delete the existing one or '
+                        'uncheck.'))
+                    self.versionNameEdit[number].setFocus()
+                    return False
+                elif os.path.exists(os.path.join(self.newpath, 
+                    self.clean_filename(version_name))):
+                    critical_error_message_box(
+                        translate('BiblesPlugin.UpgradeWizardForm', 
+                        'Bible Exists'),
+                        translate('BiblesPlugin.UpgradeWizardForm',
+                        'This Bible already exists. Please upgrade '
+                        'a different Bible, delete the existing one or '
+                        'uncheck.'))
+                    self.versionNameEdit[number].setFocus()
+                    return False
+            return True
+        if self.currentPage() == self.progressPage:
+            return True
+
+    def setDefaults(self):
+        """
+        Set default values for the wizard pages.
+        """
+        log.debug(u'BibleUpgrade setDefaults')
+        settings = QtCore.QSettings()
+        settings.beginGroup(self.plugin.settingsSection)
+        self.stop_import_flag = False
+        self.success.clear()
+        self.newbibles.clear()
+        self.clearScrollArea()
+        self.files = SettingsManager.get_files(self.oldsettingsSection, 
+            self.suffix)
+        self.addScrollArea()
+        self.customSignals()
+        self.retranslateUi()
+        self.maxBibles = len(self.files)
+        self.finishButton.setVisible(False)
+        self.cancelButton.setVisible(True)
+        for number, filename in enumerate(self.files):
+            self.checkBox[number].setCheckState(2)
+            if os.path.exists(os.path.join(self.newpath, filename)):
+                self.verticalWidget[number].show()
+                self.formWidget[number].show()
+            else:
+                self.verticalWidget[number].hide()
+                self.formWidget[number].hide()
+        self.progressBar.show()
+        self.progressLabelAfter.hide()
+        self.deleteCheckBox.hide()
+        self.deleteCheckBox.setCheckState(0)
+        self.deleteAllCheckBox.hide()
+        self.deleteAllCheckBox.setCheckState(0)
+        self.restart()
+        settings.endGroup()
+
+    def preWizard(self):
+        """
+        Prepare the UI for the upgrade.
+        """
+        OpenLPWizard.preWizard(self)
+        self.progressLabel.setText(translate(
+            'BiblesPlugin.UpgradeWizardForm',
+            'Starting upgrading bible(s)...'))
+        Receiver.send_message(u'openlp_process_events')
+
+    def performWizard(self):
+        """
+        Perform the actual upgrade.
+        """
+        include_webbible = False
+        proxy_server = None
+        if self.maxBibles == 0:
+            self.progressLabel.setText(
+                translate('BiblesPlugin.UpgradeWizardForm', 'Sorry, but OpenLP'
+                    ' could not find a Bible to upgrade.'))
+            self.progressBar.hide()
+            return
+        self.maxBibles = 0
+        for number, file in enumerate(self.files):
+            if self.checkBox[number].checkState() == 2:
+                self.maxBibles += 1
+        number = 0
+        for biblenumber, filename in enumerate(self.files):
+            bible_failed = False
+            self.success[biblenumber] = False
+            if not self.checkBox[biblenumber].checkState() == 2:
+                continue
+            self.progressBar.reset()
+            oldbible = OldBibleDB(self.mediaItem, path=self.oldpath, 
+                file=filename)
+            name = oldbible.get_name()
+            if name is None:
+                delete_file(os.path.join(self.oldpath, filename))
+                self.incrementProgressBar(unicode(translate(
+                    'BiblesPlugin.UpgradeWizardForm', 
+                    'Upgrading Bible %s of %s: "%s"\nFailed')) % 
+                    (number+1, self.maxBibles, name), 
+                    self.progressBar.maximum()-self.progressBar.value())
+                number += 1
+                continue
+            self.progressLabel.setText(unicode(translate(
+                'BiblesPlugin.UpgradeWizardForm', 
+                'Upgrading Bible %s of %s: "%s"\nImporting ...')) % 
+                (number+1, self.maxBibles, name))
+            if os.path.exists(os.path.join(self.newpath, filename)):
+                name = unicode(self.versionNameEdit[biblenumber].text())
+            self.newbibles[number] = BibleDB(self.mediaItem, path=self.oldpath,
+                name=name)
+            metadata = oldbible.get_metadata()
+            webbible = False
+            meta_data = {}
+            for meta in metadata:
+                meta_data[meta[u'key']] = meta[u'value']
+                if not meta[u'key'] == u'Version':
+                    self.newbibles[number].create_meta(meta[u'key'],
+                        meta[u'value'])
+                else:
+                    self.newbibles[number].create_meta(meta[u'key'], name)
+                if meta[u'key'] == u'download source':
+                    webbible = True
+                    include_webbible = True
+                if meta.has_key(u'proxy server'):
+                    proxy_server = meta[u'proxy server']
+            if webbible:
+                if meta_data[u'download source'].lower() == u'crosswalk':
+                    handler = CWExtract(proxy_server)
+                elif meta_data[u'download source'].lower() == u'biblegateway':
+                    handler = BGExtract(proxy_server)
+                elif meta_data[u'download source'].lower() == u'bibleserver':
+                    handler = BSExtract(proxy_server)
+                books = handler.get_books_from_http(meta_data[u'download name'])
+                if not books:
+                    log.exception(u'Importing books from %s - download '\
+                        u'name: "%s" failed' % (
+                        meta_data[u'download source'], 
+                        meta_data[u'download name']))
+                    delete_database(self.newpath, self.newbibles[number].\
+                        clean_filename(self.newbibles[number].get_name())) 
+                    del self.newbibles[number]
+                    critical_error_message_box(
+                        translate('BiblesPlugin.UpgradeWizardForm', 
+                        'Download Error'),
+                        translate('BiblesPlugin.UpgradeWizardForm', 
+                        'To upgrade your webbibles a Internet connection is '
+                        'necessary. Please check your Internet connection, and '
+                        'if this error continues to occur please consider '
+                        'reporting a bug.'))
+                    self.incrementProgressBar(unicode(translate(
+                        'BiblesPlugin.UpgradeWizardForm', 
+                        'Upgrading Bible %s of %s: "%s"\nFailed')) % 
+                        (number+1, self.maxBibles, name), 
+                        self.progressBar.maximum()-self.progressBar.value())
+                    number += 1
+                    continue
+                bible = BiblesResourcesDB.get_webbible(
+                    meta_data[u'download name'], 
+                    meta_data[u'download source'].lower())
+                if bible[u'language_id']:
+                    language_id = bible[u'language_id']
+                    self.newbibles[number].create_meta(u'language_id',
+                        language_id)
+                else:
+                    language_id = self.newbibles[number].get_language()
+                if not language_id:
+                    log.exception(u'Upgrading from "%s" '\
+                        'failed' % filename)
+                    delete_database(self.newpath, self.newbibles[number].\
+                        clean_filename(self.newbibles[number].get_name()))
+                    del self.newbibles[number]
+                    self.incrementProgressBar(unicode(translate(
+                        'BiblesPlugin.UpgradeWizardForm', 
+                        'Upgrading Bible %s of %s: "%s"\nFailed')) % 
+                        (number+1, self.maxBibles, name),
+                        self.progressBar.maximum()-self.progressBar.value())
+                    number += 1
+                    continue
+                self.progressBar.setMaximum(len(books))
+                for book in books:
+                    self.incrementProgressBar(unicode(translate(
+                        'BiblesPlugin.UpgradeWizardForm', 
+                        'Upgrading Bible %s of %s: "%s"\n'
+                        'Importing %s ...')) % 
+                        (number+1, self.maxBibles, name, book))
+                    book_ref_id = self.newbibles[number].\
+                        get_book_ref_id_by_name(book, language_id)
+                    if not book_ref_id:
+                        log.exception(u'Importing books from %s - download '\
+                            u'name: "%s" aborted by user' % (
+                            meta_data[u'download source'], 
+                            meta_data[u'download name']))
+                        delete_database(self.newpath, self.newbibles[number].\
+                            clean_filename(self.newbibles[number].get_name()))
+                        del self.newbibles[number]
+                        bible_failed = True
+                        break
+                    book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
+                    self.newbibles[number].create_book(book, book_ref_id, 
+                        book_details[u'testament_id'])
+            else:
+                language_id = self.newbibles[number].get_object(BibleMeta,
+                    u'language_id')
+                if not language_id:
+                    language_id = self.newbibles[number].get_language()
+                if not language_id:
+                    log.exception(u'Importing books from "%s" '\
+                        'failed' % name)
+                    delete_database(self.newpath, self.newbibles[number].\
+                        clean_filename(self.newbibles[number].get_name()))
+                    del self.newbibles[number]
+                    self.incrementProgressBar(unicode(translate(
+                        'BiblesPlugin.UpgradeWizardForm', 
+                        'Upgrading Bible %s of %s: "%s"\nFailed')) % 
+                        (number+1, self.maxBibles, name), 
+                        self.progressBar.maximum()-self.progressBar.value())
+                    number += 1
+                    continue
+                books = oldbible.get_books()
+                self.progressBar.setMaximum(len(books))
+                for book in books:
+                    self.incrementProgressBar(unicode(translate(
+                        'BiblesPlugin.UpgradeWizardForm', 
+                        'Upgrading Bible %s of %s: "%s"\n'
+                        'Importing %s ...')) % 
+                        (number+1, self.maxBibles, name, book[u'name']))
+                    book_ref_id = self.newbibles[number].\
+                        get_book_ref_id_by_name(book[u'name'], language_id)
+                    if not book_ref_id:
+                        log.exception(u'Importing books from %s " '\
+                            'failed - aborted by user' % name)
+                        delete_database(self.newpath, self.newbibles[number].\
+                            clean_filename(self.newbibles[number].get_name()))
+                        del self.newbibles[number]
+                        bible_failed = True
+                        break
+                    book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
+                    db_book = self.newbibles[number].create_book(book[u'name'],
+                        book_ref_id, book_details[u'testament_id'])
+                    verses = oldbible.get_verses(book[u'id'])
+                    for verse in verses:
+                        self.newbibles[number].create_verse(db_book.id, 
+                            int(verse[u'chapter']), 
+                            int(verse[u'verse']), unicode(verse[u'text']))
+                        Receiver.send_message(u'openlp_process_events')
+            if not bible_failed:
+                self.incrementProgressBar(unicode(translate(
+                    'BiblesPlugin.UpgradeWizardForm', 
+                    'Upgrading Bible %s of %s: "%s"\n'
+                    'Done')) % 
+                    (number+1, self.maxBibles, name))
+                self.success[biblenumber] = True
+            else:
+                self.incrementProgressBar(unicode(translate(
+                    'BiblesPlugin.UpgradeWizardForm', 
+                    'Upgrading Bible %s of %s: "%s"\nFailed')) % 
+                    (number+1, self.maxBibles, name), 
+                    self.progressBar.maximum()-self.progressBar.value())
+            number += 1
+        self.mediaItem.reloadBibles()
+        successful_import = 0
+        failed_import = 0
+        for number, success in self.success.iteritems():
+            if success == True:
+                successful_import += 1
+            elif success == False and self.checkBox[number].checkState() == 2:
+                failed_import += 1
+        if failed_import > 0:
+            failed_import_text = unicode(translate(
+                'BiblesPlugin.UpgradeWizardForm', 
+                ' - %s upgrade fail')) % failed_import
+        else:
+            failed_import_text = u''
+        if successful_import > 0:
+            if include_webbible:
+                self.progressLabel.setText(unicode(
+                    translate('BiblesPlugin.UpgradeWizardForm', 'Upgrade %s '
+                    'bible(s) successful%s.\nPlease note, that verses from '
+                    'webbibles will be downloaded\non demand and thus an '
+                    'internet connection is required.')) % 
+                    (successful_import, failed_import_text))
+            else:
+                self.progressLabel.setText(unicode(
+                    translate('BiblesPlugin.UpgradeWizardForm', 'Upgrade %s '
+                    'bible(s) successful.%s')) % (successful_import, 
+                    failed_import_text))
+            self.deleteCheckBox.show()
+            bibles = u''
+            for bible in self.newbibles.itervalues():
+                name = bible.get_name()
+                bibles += u'\n"' + name + u'"'
+            self.deleteCheckBox.setToolTip(unicode(translate(
+                'BiblesPlugin.UpgradeWizardForm', 
+                'Sucessful upgraded bible(s):%s')) % bibles)
+        else:
+            self.progressLabel.setText(
+                    translate('BiblesPlugin.UpgradeWizardForm', 'Upgrade '
+                    'failed.'))
+        self.progressLabelAfter.show()
+        self.deleteAllCheckBox.show()

=== added file 'openlp/plugins/bibles/forms/booknamedialog.py'
--- openlp/plugins/bibles/forms/booknamedialog.py	1970-01-01 00:00:00 +0000
+++ openlp/plugins/bibles/forms/booknamedialog.py	2011-04-26 18:58:23 +0000
@@ -0,0 +1,95 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection                                      #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2011 Raoul Snyman                                        #
+# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael      #
+# Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat,  #
+# Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon  #
+# Tibble, Carsten Tinggaard, Frode Woldsund                                   #
+# --------------------------------------------------------------------------- #
+# This program is free software; you can redistribute it and/or modify it     #
+# under the terms of the GNU General Public License as published by the Free  #
+# Software Foundation; version 2 of the License.                              #
+#                                                                             #
+# This program is distributed in the hope that it will be useful, but WITHOUT #
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       #
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    #
+# more details.                                                               #
+#                                                                             #
+# You should have received a copy of the GNU General Public License along     #
+# with this program; if not, write to the Free Software Foundation, Inc., 59  #
+# Temple Place, Suite 330, Boston, MA 02111-1307 USA                          #
+###############################################################################
+
+from PyQt4 import QtCore, QtGui
+
+from openlp.core.lib import translate
+from openlp.core.lib.ui import create_accept_reject_button_box
+
+class Ui_BookNameDialog(object):
+    def setupUi(self, bookNameDialog):
+        bookNameDialog.setObjectName(u'BookNameDialog')
+        bookNameDialog.resize(400, 175)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, 
+            QtGui.QSizePolicy.MinimumExpanding)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(bookNameDialog.sizePolicy()
+            .hasHeightForWidth())
+        bookNameDialog.setSizePolicy(sizePolicy)
+        self.widget = QtGui.QWidget(bookNameDialog)
+        self.widget.setGeometry(QtCore.QRect(10, 15, 381, 151))
+        self.widget.setObjectName(u'widget')
+        self.verticalLayout = QtGui.QVBoxLayout(self.widget)
+        self.verticalLayout.setObjectName(u'verticalLayout')
+        self.headlineLabel = QtGui.QLabel(self.widget)
+        font = QtGui.QFont()
+        font.setFamily(u'Arial')
+        font.setPointSize(11)
+        font.setWeight(75)
+        font.setBold(True)
+        self.headlineLabel.setFont(font)
+        self.headlineLabel.setObjectName(u'HeadlineLabel')
+        self.verticalLayout.addWidget(self.headlineLabel)
+        self.infoLabel = QtGui.QLabel(self.widget)
+        self.infoLabel.setObjectName(u'InfoLabel')
+        self.verticalLayout.addWidget(self.infoLabel)
+        self.formLayout = QtGui.QFormLayout()
+        self.formLayout.setObjectName(u'formLayout')
+        self.requestLabel = QtGui.QLabel(self.widget)
+        self.requestLabel.setObjectName(u'RequestLabel')
+        self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, 
+            self.requestLabel)
+        self.requestComboBox = QtGui.QComboBox(self.widget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, 
+            QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.requestComboBox.sizePolicy()
+            .hasHeightForWidth())
+        self.requestComboBox.setSizePolicy(sizePolicy)
+        self.requestComboBox.setObjectName(u'RequestComboBox')
+        self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, 
+            self.requestComboBox)
+        self.verticalLayout.addLayout(self.formLayout)
+        spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, 
+            QtGui.QSizePolicy.Expanding)
+        self.verticalLayout.addItem(spacerItem)
+        self.formLayout.addWidget(
+            create_accept_reject_button_box(bookNameDialog))
+        self.retranslateUi(bookNameDialog)
+        QtCore.QMetaObject.connectSlotsByName(bookNameDialog)
+
+    def retranslateUi(self, bookNameDialog):
+        bookNameDialog.setWindowTitle(
+            translate('BiblesPlugin.BookNameDialog', 'Choose Book'))
+        self.headlineLabel.setText(
+            translate('BiblesPlugin.BookNameDialog', 'Choose Book:'))
+        self.infoLabel.setText(translate('BiblesPlugin.BookNameDialog', 
+            'The following books cannot be clearly attributed. \n'
+            'Please choose the book it is.'))
+        self.requestLabel.setText(translate('BiblesPlugin.BookNameDialog', 
+            'Book:'))

=== added file 'openlp/plugins/bibles/forms/booknameform.py'
--- openlp/plugins/bibles/forms/booknameform.py	1970-01-01 00:00:00 +0000
+++ openlp/plugins/bibles/forms/booknameform.py	2011-04-26 18:58:23 +0000
@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection                                      #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2011 Raoul Snyman                                        #
+# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael      #
+# Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat,  #
+# Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon  #
+# Tibble, Carsten Tinggaard, Frode Woldsund                                   #
+# --------------------------------------------------------------------------- #
+# This program is free software; you can redistribute it and/or modify it     #
+# under the terms of the GNU General Public License as published by the Free  #
+# Software Foundation; version 2 of the License.                              #
+#                                                                             #
+# This program is distributed in the hope that it will be useful, but WITHOUT #
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       #
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    #
+# more details.                                                               #
+#                                                                             #
+# You should have received a copy of the GNU General Public License along     #
+# with this program; if not, write to the Free Software Foundation, Inc., 59  #
+# Temple Place, Suite 330, Boston, MA 02111-1307 USA                          #
+###############################################################################
+
+"""
+Module implementing BookNameForm.
+"""
+import logging
+
+from PyQt4.QtGui import QDialog
+
+from openlp.core.lib import translate
+from openlp.core.lib.ui import critical_error_message_box
+from openlp.plugins.bibles.forms.booknamedialog import \
+    Ui_BookNameDialog
+from openlp.plugins.bibles.lib.db import BiblesResourcesDB
+
+log = logging.getLogger(__name__)
+
+class BookNameForm(QDialog, Ui_BookNameDialog):
+    """
+    Class to manage a dialog which help the user to refer a book name a 
+    to a english book name
+    """
+    log.info(u'BookNameForm loaded')
+    
+    def __init__(self, parent = None):
+        """
+        Constructor
+        """
+        QDialog.__init__(self, parent)
+        self.setupUi(self)
+
+    def exec_(self, name):
+        items = []
+        self.requestComboBox.addItem(u'')
+        self.requestLabel.setText(name)
+        items = BiblesResourcesDB.get_books()
+        for item in items:
+            self.requestComboBox.addItem(item[u'name'])
+        return QDialog.exec_(self)
+    
+    def accept(self):
+        if self.requestComboBox.currentText() == u'':
+            critical_error_message_box(
+                message=translate('BiblesPlugin.BookNameForm',
+                'You need to choose a book.'))
+            self.requestComboBox.setFocus()
+            return False
+        else:
+            return QDialog.accept(self)

=== added file 'openlp/plugins/bibles/forms/languagedialog.py'
--- openlp/plugins/bibles/forms/languagedialog.py	1970-01-01 00:00:00 +0000
+++ openlp/plugins/bibles/forms/languagedialog.py	2011-04-26 18:58:23 +0000
@@ -0,0 +1,94 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection                                      #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2011 Raoul Snyman                                        #
+# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael      #
+# Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat,  #
+# Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon  #
+# Tibble, Carsten Tinggaard, Frode Woldsund                                   #
+# --------------------------------------------------------------------------- #
+# This program is free software; you can redistribute it and/or modify it     #
+# under the terms of the GNU General Public License as published by the Free  #
+# Software Foundation; version 2 of the License.                              #
+#                                                                             #
+# This program is distributed in the hope that it will be useful, but WITHOUT #
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       #
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    #
+# more details.                                                               #
+#                                                                             #
+# You should have received a copy of the GNU General Public License along     #
+# with this program; if not, write to the Free Software Foundation, Inc., 59  #
+# Temple Place, Suite 330, Boston, MA 02111-1307 USA                          #
+###############################################################################
+
+from PyQt4 import QtCore, QtGui
+
+from openlp.core.lib import translate
+from openlp.core.lib.ui import create_accept_reject_button_box
+
+class Ui_LanguageDialog(object):
+    def setupUi(self, languageDialog):
+        languageDialog.setObjectName(u'LanugageDialog')
+        languageDialog.resize(400, 175)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, 
+            QtGui.QSizePolicy.MinimumExpanding)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(languageDialog.sizePolicy()
+            .hasHeightForWidth())
+        languageDialog.setSizePolicy(sizePolicy)
+        self.widget = QtGui.QWidget(languageDialog)
+        self.widget.setGeometry(QtCore.QRect(10, 15, 381, 151))
+        self.widget.setObjectName(u'widget')
+        self.verticalLayout = QtGui.QVBoxLayout(self.widget)
+        self.verticalLayout.setObjectName(u'verticalLayout')
+        self.headlineLabel = QtGui.QLabel(self.widget)
+        font = QtGui.QFont()
+        font.setFamily(u'Arial')
+        font.setPointSize(11)
+        font.setWeight(75)
+        font.setBold(True)
+        self.headlineLabel.setFont(font)
+        self.headlineLabel.setObjectName(u'HeadlineLabel')
+        self.verticalLayout.addWidget(self.headlineLabel)
+        self.infoLabel = QtGui.QLabel(self.widget)
+        self.infoLabel.setObjectName(u'InfoLabel')
+        self.verticalLayout.addWidget(self.infoLabel)
+        self.formLayout = QtGui.QFormLayout()
+        self.formLayout.setObjectName(u'formLayout')
+        self.requestLabel = QtGui.QLabel(self.widget)
+        self.requestLabel.setObjectName(u'RequestLabel')
+        self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, 
+            self.requestLabel)
+        self.requestComboBox = QtGui.QComboBox(self.widget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, 
+            QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.requestComboBox.sizePolicy()
+            .hasHeightForWidth())
+        self.requestComboBox.setSizePolicy(sizePolicy)
+        self.requestComboBox.setObjectName(u'RequestComboBox')
+        self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, 
+            self.requestComboBox)
+        self.verticalLayout.addLayout(self.formLayout)
+        spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, 
+            QtGui.QSizePolicy.Expanding)
+        self.verticalLayout.addItem(spacerItem)
+        self.formLayout.addWidget(
+            create_accept_reject_button_box(languageDialog))
+        self.retranslateUi(languageDialog)
+        QtCore.QMetaObject.connectSlotsByName(languageDialog)
+
+    def retranslateUi(self, languageDialog):
+        languageDialog.setWindowTitle(
+            translate('BiblesPlugin.LanguageDialog', 'Choose Language'))
+        self.headlineLabel.setText(
+            translate('BiblesPlugin.LanguageDialog', 'Choose Language:'))
+        self.infoLabel.setText(translate('BiblesPlugin.LanguageDialog', 
+            'Please choose the language the bible is.'))
+        self.requestLabel.setText(translate('BiblesPlugin.languageDialog', 
+            'Language:'))

=== added file 'openlp/plugins/bibles/forms/languageform.py'
--- openlp/plugins/bibles/forms/languageform.py	1970-01-01 00:00:00 +0000
+++ openlp/plugins/bibles/forms/languageform.py	2011-04-26 18:58:23 +0000
@@ -0,0 +1,71 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection                                      #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2011 Raoul Snyman                                        #
+# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael      #
+# Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat,  #
+# Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon  #
+# Tibble, Carsten Tinggaard, Frode Woldsund                                   #
+# --------------------------------------------------------------------------- #
+# This program is free software; you can redistribute it and/or modify it     #
+# under the terms of the GNU General Public License as published by the Free  #
+# Software Foundation; version 2 of the License.                              #
+#                                                                             #
+# This program is distributed in the hope that it will be useful, but WITHOUT #
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       #
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    #
+# more details.                                                               #
+#                                                                             #
+# You should have received a copy of the GNU General Public License along     #
+# with this program; if not, write to the Free Software Foundation, Inc., 59  #
+# Temple Place, Suite 330, Boston, MA 02111-1307 USA                          #
+###############################################################################
+
+"""
+Module implementing LanguageForm.
+"""
+import logging
+
+from PyQt4.QtGui import QDialog
+
+from openlp.core.lib import translate
+from openlp.core.lib.ui import critical_error_message_box
+from openlp.plugins.bibles.forms.languagedialog import \
+    Ui_LanguageDialog
+from openlp.plugins.bibles.lib.db import BiblesResourcesDB
+
+log = logging.getLogger(__name__)
+
+class LanguageForm(QDialog, Ui_LanguageDialog):
+    """
+    Class to manage a dialog which ask the user for a language.
+    """
+    log.info(u'LanguageForm loaded')
+    
+    def __init__(self, parent = None):
+        """
+        Constructor
+        """
+        QDialog.__init__(self, parent)
+        self.setupUi(self)
+
+    def exec_(self):
+        items = []
+        self.requestComboBox.addItem(u'')
+        items = BiblesResourcesDB.get_languages()
+        for item in items:
+            self.requestComboBox.addItem(item[u'name'])
+        return QDialog.exec_(self)
+    
+    def accept(self):
+        if self.requestComboBox.currentText() == u'':
+            critical_error_message_box(
+                message=translate('BiblesPlugin.LanguageForm',
+                'You need to choose a language.'))
+            self.requestComboBox.setFocus()
+            return False
+        else:
+            return QDialog.accept(self)

=== modified file 'openlp/plugins/bibles/lib/csvbible.py'
--- openlp/plugins/bibles/lib/csvbible.py	2011-03-24 19:04:02 +0000
+++ openlp/plugins/bibles/lib/csvbible.py	2011-04-26 18:58:23 +0000
@@ -70,7 +70,7 @@
 import csv
 
 from openlp.core.lib import Receiver, translate
-from openlp.plugins.bibles.lib.db import BibleDB, Testament
+from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB#, Testament
 
 log = logging.getLogger(__name__)
 
@@ -78,6 +78,8 @@
     """
     This class provides a specialisation for importing of CSV Bibles.
     """
+    log.info(u'CSVBible loaded')
+
     def __init__(self, parent, **kwargs):
         """
         Loads a Bible from a set of CVS files.
@@ -86,47 +88,9 @@
         """
         log.info(self.__class__.__name__)
         BibleDB.__init__(self, parent, **kwargs)
-        try:
-            self.testamentsfile = kwargs[u'testamentsfile']
-        except KeyError:
-            self.testamentsfile = None
         self.booksfile = kwargs[u'booksfile']
         self.versesfile = kwargs[u'versefile']
 
-    def setup_testaments(self):
-        """
-        Overrides parent method so we can handle importing a testament file.
-        """
-        if self.testamentsfile:
-            self.wizard.progressBar.setMinimum(0)
-            self.wizard.progressBar.setMaximum(2)
-            self.wizard.progressBar.setValue(0)
-            testaments_file = None
-            try:
-                details = get_file_encoding(self.testamentsfile)
-                testaments_file = open(self.testamentsfile, 'rb')
-                testaments_reader = csv.reader(testaments_file, delimiter=',',
-                    quotechar='"')
-                for line in testaments_reader:
-                    if self.stop_import_flag:
-                        break
-                    self.wizard.incrementProgressBar(unicode(
-                        translate('BibleDB.Wizard',
-                        'Importing testaments... %s')) %
-                        unicode(line[1], details['encoding']), 0)
-                    self.save_object(Testament.populate(
-                        name=unicode(line[1], details['encoding'])))
-                Receiver.send_message(u'openlp_process_events')
-            except (IOError, IndexError):
-                log.exception(u'Loading testaments from file failed')
-            finally:
-                if testaments_file:
-                    testaments_file.close()
-            self.wizard.incrementProgressBar(unicode(translate(
-                'BibleDB.Wizard', 'Importing testaments... done.')), 2)
-        else:
-            BibleDB.setup_testaments(self)
-
     def do_import(self):
         """
         Import the bible books and verses.
@@ -135,6 +99,11 @@
         self.wizard.progressBar.setMinimum(0)
         self.wizard.progressBar.setMaximum(66)
         success = True
+        language_id = self.get_language()
+        if not language_id:
+            log.exception(u'Importing books from "%s" '\
+                'failed' % self.filename)
+            return False
         books_file = None
         book_list = {}
         # Populate the Tables
@@ -148,8 +117,15 @@
                 self.wizard.incrementProgressBar(unicode(
                     translate('BibleDB.Wizard', 'Importing books... %s')) %
                     unicode(line[2], details['encoding']))
+                book_ref_id = self.get_book_ref_id_by_name(
+                    unicode(line[2], details['encoding']), language_id)
+                if not book_ref_id:
+                    log.exception(u'Importing books from "%s" '\
+                        'failed' % self.booksfile)
+                    return False
+                book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
                 self.create_book(unicode(line[2], details['encoding']),
-                    unicode(line[3], details['encoding']), int(line[1]))
+                    book_ref_id, book_details[u'testament_id'])
                 book_list[int(line[0])] = unicode(line[2], details['encoding'])
             Receiver.send_message(u'openlp_process_events')
         except (IOError, IndexError):

=== modified file 'openlp/plugins/bibles/lib/db.py'
--- openlp/plugins/bibles/lib/db.py	2011-04-13 18:53:05 +0000
+++ openlp/plugins/bibles/lib/db.py	2011-04-26 18:58:23 +0000
@@ -26,16 +26,19 @@
 
 import logging
 import chardet
+import os
 import re
+import sqlite3
 
 from PyQt4 import QtCore
 from sqlalchemy import Column, ForeignKey, or_, Table, types
 from sqlalchemy.orm import class_mapper, mapper, relation
 from sqlalchemy.orm.exc import UnmappedClassError
 
-from openlp.core.lib import Receiver, translate
+from openlp.core.lib import Receiver, translate, check_directory_exists
 from openlp.core.lib.db import BaseModel, init_db, Manager
 from openlp.core.lib.ui import critical_error_message_box
+from openlp.core.utils import AppLocation
 
 log = logging.getLogger(__name__)
 
@@ -46,13 +49,6 @@
     pass
 
 
-class Testament(BaseModel):
-    """
-    Bible Testaments
-    """
-    pass
-
-
 class Book(BaseModel):
     """
     Song model
@@ -66,7 +62,6 @@
     """
     pass
 
-
 def init_schema(url):
     """
     Setup a bible database connection and initialise the database schema.
@@ -80,19 +75,17 @@
         Column(u'key', types.Unicode(255), primary_key=True, index=True),
         Column(u'value', types.Unicode(255)),
     )
-    testament_table = Table(u'testament', metadata,
-        Column(u'id', types.Integer, primary_key=True),
-        Column(u'name', types.Unicode(50)),
-    )
+
     book_table = Table(u'book', metadata,
         Column(u'id', types.Integer, primary_key=True),
-        Column(u'testament_id', types.Integer, ForeignKey(u'testament.id')),
+        Column(u'book_reference_id', types.Integer, index=True),
+        Column(u'testament_reference_id', types.Integer),
         Column(u'name', types.Unicode(50), index=True),
-        Column(u'abbreviation', types.Unicode(5), index=True),
     )
     verse_table = Table(u'verse', metadata,
         Column(u'id', types.Integer, primary_key=True, index=True),
-        Column(u'book_id', types.Integer, ForeignKey(u'book.id'), index=True),
+        Column(u'book_id', types.Integer, ForeignKey(
+            u'book.id'), index=True),
         Column(u'chapter', types.Integer, index=True),
         Column(u'verse', types.Integer, index=True),
         Column(u'text', types.UnicodeText, index=True),
@@ -103,11 +96,6 @@
     except UnmappedClassError:
         mapper(BibleMeta, meta_table)
     try:
-        class_mapper(Testament)
-    except UnmappedClassError:
-        mapper(Testament, testament_table,
-            properties={'books': relation(Book, backref='testament')})
-    try:
         class_mapper(Book)
     except UnmappedClassError:
         mapper(Book, book_table,
@@ -128,6 +116,7 @@
     methods, but benefit from the database methods in here via inheritance,
     rather than depending on yet another object.
     """
+    log.info(u'BibleDB loaded')
 
     def __init__(self, parent, **kwargs):
         """
@@ -158,9 +147,11 @@
             self.file = self.clean_filename(self.name)
         if u'file' in kwargs:
             self.file = kwargs[u'file']
-        Manager.__init__(self, u'bibles', init_schema, self.file)
+        Manager.__init__(self, u'bibles/bibles', init_schema, self.file)
         if u'file' in kwargs:
             self.get_name()
+        if u'path' in kwargs:
+            self.path = kwargs[u'path']
         self.wizard = None
         QtCore.QObject.connect(Receiver.get_receiver(),
             QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import)
@@ -205,33 +196,25 @@
         """
         self.wizard = wizard
         self.create_meta(u'dbversion', u'2')
-        self.setup_testaments()
         return self.name
 
-    def setup_testaments(self):
-        """
-        Initialise the testaments section of a bible with suitable defaults.
-        """
-        self.save_object(Testament.populate(name=u'Old Testament'))
-        self.save_object(Testament.populate(name=u'New Testament'))
-        self.save_object(Testament.populate(name=u'Apocrypha'))
-
-    def create_book(self, name, abbrev, testament=1):
+    def create_book(self, name, bk_ref_id, testament=1):
         """
         Add a book to the database.
 
         ``name``
             The name of the book.
 
-        ``abbrev``
-            The abbreviation of the book.
+        ``bk_ref_id``
+            The book_reference_id from bibles_resources.sqlite of the book.
 
         ``testament``
-            *Defaults to 1.* The id of the testament this book belongs to.
+            *Defaults to 1.* The testament_reference_id from 
+            bibles_resources.sqlite of the testament this book belongs to.
         """
-        log.debug(u'create_book %s,%s', name, abbrev)
-        book = Book.populate(name=name, abbreviation=abbrev,
-            testament_id=testament)
+        log.debug(u'BibleDB.create_book("%s", "%s")', name, bk_ref_id)
+        book = Book.populate(name=name, book_reference_id=bk_ref_id,
+            testament_reference_id=testament)
         self.save_object(book)
         return book
 
@@ -249,7 +232,7 @@
             A dict of the verses to be inserted. The key is the verse number,
             and the value is the verse text.
         """
-        log.debug(u'create_chapter %s,%s', book_id, chapter)
+        log.debug(u'BibleDBcreate_chapter("%s", "%s")', book_id, chapter)
         # Text list has book and chapter as first two elements of the array.
         for verse_number, verse_text in textlist.iteritems():
             verse = Verse.populate(
@@ -299,7 +282,9 @@
         ``value``
             The value for this instance.
         """
-        log.debug(u'save_meta %s/%s', key, value)
+        if not isinstance(value, unicode):
+            value = unicode(value)
+        log.debug(u'BibleDB.save_meta("%s/%s")', key, value)
         self.save_object(BibleMeta.populate(key=key, value=value))
 
     def get_book(self, book):
@@ -309,20 +294,62 @@
         ``book``
             The name of the book to return.
         """
-        log.debug(u'BibleDb.get_book("%s")', book)
-        db_book = self.get_object_filtered(Book, Book.name.like(book + u'%'))
-        if db_book is None:
-            db_book = self.get_object_filtered(Book,
-                Book.abbreviation.like(book + u'%'))
-        return db_book
+        log.debug(u'BibleDB.get_book("%s")', book)
+        return self.get_object_filtered(Book, Book.name.like(book + u'%'))
 
     def get_books(self):
         """
         A wrapper so both local and web bibles have a get_books() method that
         manager can call. Used in the media manager advanced search tab.
         """
+        log.debug(u'BibleDB.get_books()')
         return self.get_all_objects(Book, order_by_ref=Book.id)
 
+    def get_book_by_book_ref_id(self, id):
+        """
+        Return a book object from the database.
+
+        ``id``
+            The reference id of the book to return.
+        """
+        log.debug(u'BibleDB.get_book_by_book_ref_id("%s")', id)
+        return self.get_object_filtered(Book, Book.book_reference_id.like(id))
+
+    def get_book_ref_id_by_name(self, book, language_id=None):
+        log.debug(u'BibleDB.get_book_ref_id_by_name:("%s", "%s")', book, 
+            language_id)
+        if BiblesResourcesDB.get_book(book):
+            book_temp = BiblesResourcesDB.get_book(book)
+            book_id = book_temp[u'id']
+        elif BiblesResourcesDB.get_alternative_book_name(book, language_id):
+            book_id = BiblesResourcesDB.get_alternative_book_name(book, 
+                language_id)
+        elif AlternativeBookNamesDB.get_book_reference_id(book, 
+            language_id):
+            book_id = AlternativeBookNamesDB.get_book_reference_id(
+                book, language_id)
+        else:
+            from openlp.plugins.bibles.forms import BookNameForm
+            book_ref = None
+            book_name = BookNameForm(self.wizard)
+            if book_name.exec_(book):
+                book_ref = unicode(book_name.requestComboBox.currentText())
+            if not book_ref:
+                return None
+            else:
+                book_temp = BiblesResourcesDB.get_book(book_ref)
+            if book_temp:
+                book_id = book_temp[u'id']
+            else:
+                return None
+            if book_id:
+                AlternativeBookNamesDB.create_alternative_book_name(
+                    book, book_id, language_id)
+        if book_id:
+            return book_id
+        else:
+            return None
+
     def get_verses(self, reference_list):
         """
         This is probably the most used function. It retrieves the list of
@@ -332,24 +359,24 @@
             This is the list of references the media manager item wants. It is
             a list of tuples, with the following format::
 
-                (book, chapter, start_verse, end_verse)
+                (book_reference_id, chapter, start_verse, end_verse)
 
             Therefore, when you are looking for multiple items, simply break
             them up into references like this, bundle them into a list. This
             function then runs through the list, and returns an amalgamated
             list of ``Verse`` objects. For example::
 
-                [(u'Genesis', 1, 1, 1), (u'Genesis', 2, 2, 3)]
+                [(u'35', 1, 1, 1), (u'35', 2, 2, 3)]
         """
-        log.debug(u'BibleDB.get_verses: %s', reference_list)
+        log.debug(u'BibleDB.get_verses("%s")', reference_list)
         verse_list = []
-        for book, chapter, start_verse, end_verse in reference_list:
-            db_book = self.get_book(book)
+        for book_id, chapter, start_verse, end_verse in reference_list:
+            db_book = self.get_book_by_book_ref_id(book_id)
             if db_book:
-                book = db_book.name
-                log.debug(u'Book name corrected to "%s"', book)
+                book_id = db_book.book_reference_id
+                log.debug(u'Book name corrected to "%s"', db_book.name)
                 if end_verse == -1:
-                    end_verse = self.get_verse_count(book, chapter)
+                    end_verse = self.get_verse_count(book_id, chapter)
                 verses = self.session.query(Verse)\
                     .filter_by(book_id=db_book.id)\
                     .filter_by(chapter=chapter)\
@@ -397,18 +424,18 @@
         Return the number of chapters in a book.
 
         ``book``
-            The book to get the chapter count for.
+            The book object to get the chapter count for.
         """
-        log.debug(u'BibleDB.get_chapter_count("%s")', book)
+        log.debug(u'BibleDB.get_chapter_count("%s")', book.name)
         count = self.session.query(Verse.chapter).join(Book)\
-            .filter(Book.name==book)\
+            .filter(Book.book_reference_id==book.book_reference_id)\
             .distinct().count()
         if not count:
             return 0
         else:
             return count
 
-    def get_verse_count(self, book, chapter):
+    def get_verse_count(self, book_id, chapter):
         """
         Return the number of verses in a chapter.
 
@@ -418,9 +445,9 @@
         ``chapter``
             The chapter to get the verse count for.
         """
-        log.debug(u'BibleDB.get_verse_count("%s", %s)', book, chapter)
+        log.debug(u'BibleDB.get_verse_count("%s", "%s")', book_id, chapter)
         count = self.session.query(Verse).join(Book)\
-            .filter(Book.name==book)\
+            .filter(Book.book_reference_id==book_id)\
             .filter(Verse.chapter==chapter)\
             .count()
         if not count:
@@ -428,6 +455,28 @@
         else:
             return count
 
+    def get_language(self):
+        """
+        If no language is given it calls a dialog window where the user could 
+        choose the bible language.
+        Return the language id of a bible.
+
+        ``book``
+            The language the bible is.
+        """
+        log.debug(u'BibleDB.get_language()')
+        from openlp.plugins.bibles.forms import LanguageForm
+        language = None
+        lang = LanguageForm(self.wizard)
+        if lang.exec_():
+            language = unicode(lang.requestComboBox.currentText())
+        if not language:
+            return False
+        language = BiblesResourcesDB.get_language(language)
+        language_id = language[u'id']
+        self.create_meta(u'language_id', language_id)
+        return language_id
+
     def dump_bible(self):
         """
         Utility debugging method to dump the contents of a bible.
@@ -439,3 +488,566 @@
         log.debug(u'...............................Verses ')
         verses = self.session.query(Verse).all()
         log.debug(verses)
+
+
+class BiblesResourcesDB(QtCore.QObject, Manager):
+    """
+    This class represents the database-bound Bible Resources. It provide
+    some resources which are used in the Bibles plugin.
+    A wrapper class around a small SQLite database which contains the download
+    resources, a biblelist from the different download resources, the books,
+    chapter counts and verse counts for the web download Bibles, a language 
+    reference, the testament reference and some alternative book names. This 
+    class contains a singleton "cursor" so that only one connection to the 
+    SQLite database is ever used.
+    """
+    cursor = None
+
+    @staticmethod
+    def get_cursor():
+        """
+        Return the cursor object. Instantiate one if it doesn't exist yet.
+        """
+        if BiblesResourcesDB.cursor is None:
+            filepath = os.path.join(
+                AppLocation.get_directory(AppLocation.PluginsDir), u'bibles',
+                u'resources', u'bibles_resources.sqlite')
+            conn = sqlite3.connect(filepath)
+            BiblesResourcesDB.cursor = conn.cursor()
+        return BiblesResourcesDB.cursor
+
+    @staticmethod
+    def run_sql(query, parameters=()):
+        """
+        Run an SQL query on the database, returning the results.
+
+        ``query``
+            The actual SQL query to run.
+
+        ``parameters``
+            Any variable parameters to add to the query.
+        """
+        cursor = BiblesResourcesDB.get_cursor()
+        cursor.execute(query, parameters)
+        return cursor.fetchall()
+
+    @staticmethod
+    def get_books():
+        """
+        Return a list of all the books of the Bible.
+        """
+        log.debug(u'BiblesResourcesDB.get_books()')
+        books = BiblesResourcesDB.run_sql(u'SELECT id, testament_id, name, '
+                u'abbreviation, chapters FROM book_reference ORDER BY id')
+        return [
+            {
+            u'id': book[0],
+            u'testament_id': book[1],
+            u'name': unicode(book[2]),
+            u'abbreviation': unicode(book[3]),
+            u'chapters': book[4]
+            }
+            for book in books
+        ]
+
+    @staticmethod
+    def get_book(name):
+        """
+        Return a book by name or abbreviation.
+
+        ``name``
+            The name or abbreviation of the book.
+        """
+        log.debug(u'BiblesResourcesDB.get_book("%s")', name)
+        if not isinstance(name, unicode):
+            name = unicode(name)
+        books = BiblesResourcesDB.run_sql(u'SELECT id, testament_id, name, '
+                u'abbreviation, chapters FROM book_reference WHERE name = ? OR '
+                u'abbreviation = ?', (name, name))
+        if books:
+            return {
+                u'id': books[0][0],
+                u'testament_id': books[0][1],
+                u'name': unicode(books[0][2]),
+                u'abbreviation': unicode(books[0][3]),
+                u'chapters': books[0][4]
+            }
+        else:
+            return None
+
+    @staticmethod
+    def get_book_by_id(id):
+        """
+        Return a book by id.
+
+        ``id``
+            The id of the book.
+        """
+        log.debug(u'BiblesResourcesDB.get_book_by_id("%s")', id)
+        if not isinstance(id, int):
+            id = int(id)
+        books = BiblesResourcesDB.run_sql(u'SELECT id, testament_id, name, '
+                u'abbreviation, chapters FROM book_reference WHERE id = ?', 
+                (id, ))
+        if books:
+            return {
+                u'id': books[0][0],
+                u'testament_id': books[0][1],
+                u'name': unicode(books[0][2]),
+                u'abbreviation': unicode(books[0][3]),
+                u'chapters': books[0][4]
+            }
+        else:
+            return None
+
+    @staticmethod
+    def get_chapter(book_id, chapter):
+        """
+        Return the chapter details for a specific chapter of a book.
+
+        ``book_id``
+            The id of a book.
+
+        ``chapter``
+            The chapter number.
+        """
+        log.debug(u'BiblesResourcesDB.get_chapter("%s", "%s")', book_id, 
+            chapter)
+        if not isinstance(chapter, int):
+            chapter = int(chapter)
+        chapters = BiblesResourcesDB.run_sql(u'SELECT id, book_reference_id, '
+            u'chapter, verse_count FROM chapters WHERE book_reference_id = ?', 
+            (book_id,))
+        if chapters:
+            return {
+                u'id': chapters[chapter-1][0],
+                u'book_reference_id': chapters[chapter-1][1],
+                u'chapter': chapters[chapter-1][2],
+                u'verse_count': chapters[chapter-1][3]
+            }
+        else:
+            return None
+
+    @staticmethod
+    def get_chapter_count(book_id):
+        """
+        Return the number of chapters in a book.
+
+        ``book_id``
+            The id of the book.
+        """
+        log.debug(u'BiblesResourcesDB.get_chapter_count("%s")', book_id)
+        details = BiblesResourcesDB.get_book_by_id(book_id)
+        if details:
+            return details[u'chapters']
+        return 0
+
+    @staticmethod
+    def get_verse_count(book_id, chapter):
+        """
+        Return the number of verses in a chapter.
+
+        ``book``
+            The id of the book.
+
+        ``chapter``
+            The number of the chapter.
+        """
+        log.debug(u'BiblesResourcesDB.get_verse_count("%s", "%s")', book_id,  
+            chapter)
+        details = BiblesResourcesDB.get_chapter(book_id, chapter)
+        if details:
+            return details[u'verse_count']
+        return 0
+
+    @staticmethod
+    def get_download_source(source):
+        """
+        Return a download_source_id by source.
+
+        ``name``
+            The name or abbreviation of the book.
+        """
+        log.debug(u'BiblesResourcesDB.get_download_source("%s")', source)
+        if not isinstance(source, unicode):
+            source = unicode(source)
+        source = source.title()
+        dl_source = BiblesResourcesDB.run_sql(u'SELECT id, source FROM '
+                u'download_source WHERE source = ?', (source.lower(),))
+        if dl_source:
+            return {
+                u'id': dl_source[0][0],
+                u'source': dl_source[0][1]
+            }
+        else:
+            return None
+    
+    @staticmethod
+    def get_webbibles(source):
+        """
+        Return the bibles a webbible provide for download.
+
+        ``source``
+            The source of the webbible.
+        """
+        log.debug(u'BiblesResourcesDB.get_webbibles("%s")', source)
+        if not isinstance(source,  unicode):
+            source = unicode(source)
+        source = BiblesResourcesDB.get_download_source(source)
+        bibles = BiblesResourcesDB.run_sql(u'SELECT id, name, abbreviation, '
+            u'language_id, download_source_id FROM webbibles WHERE '
+            u'download_source_id = ?', (source[u'id'],))
+        if bibles:
+            return [
+                {
+                u'id': bible[0],
+                u'name': bible[1],
+                u'abbreviation': bible[2],
+                u'language_id': bible[3], 
+                u'download_source_id': bible[4]
+                }
+                for bible in bibles
+            ]
+        else:
+            return None
+
+    @staticmethod
+    def get_webbible(abbreviation, source):
+        """
+        Return the bibles a webbible provide for download.
+
+        ``abbreviation``
+            The abbreviation of the webbible.
+            
+        ``source``
+            The source of the webbible.
+        """
+        log.debug(u'BiblesResourcesDB.get_webbibles("%s", "%s")', abbreviation, 
+            source)
+        if not isinstance(abbreviation, unicode):
+            abbreviation = unicode(abbreviation)
+        if not isinstance(source, unicode):
+            source = unicode(source)
+        source = BiblesResourcesDB.get_download_source(source)
+        bible = BiblesResourcesDB.run_sql(u'SELECT id, name, abbreviation, '
+            u'language_id, download_source_id FROM webbibles WHERE '
+            u'download_source_id = ? AND abbreviation = ?', (source[u'id'], 
+            abbreviation))
+        if bible:
+            return {
+                u'id': bible[0][0],
+                u'name': bible[0][1],
+                u'abbreviation': bible[0][2],
+                u'language_id': bible[0][3], 
+                u'download_source_id': bible[0][4]
+                }
+        else:
+            return None
+
+    @staticmethod
+    def get_alternative_book_name(name, language_id=None):
+        """
+        Return a book_reference_id if the name matches.
+
+        ``name``
+            The name to search the id.
+            
+        ``language_id``
+            The language_id for which language should be searched
+        """
+        log.debug(u'BiblesResourcesDB.get_alternative_book_name("%s", "%s")', 
+            name, language_id)
+        if language_id:
+            id = BiblesResourcesDB.run_sql(u'SELECT book_reference_id '
+                u'FROM alternative_book_names WHERE name = ? and language_id '
+                u'= ? ORDER BY id', (name, language_id))
+        else:
+            id = BiblesResourcesDB.run_sql(u'SELECT book_reference_id '
+                u'FROM alternative_book_names WHERE name = ? ORDER BY id',
+                (name, ))
+        if id:
+            return int(id[0][0])
+        else:
+            return None
+
+    @staticmethod
+    def get_language(name):
+        """
+        Return a dict containing the language id, name and code by name or 
+        abbreviation.
+
+        ``name``
+            The name or abbreviation of the language.
+        """
+        log.debug(u'BiblesResourcesDB.get_language("%s")', name)
+        if not isinstance(name, unicode):
+            name = unicode(name)
+        name = name.title()
+        language = BiblesResourcesDB.run_sql(u'SELECT id, name, code FROM '
+                u'language WHERE name = ? OR code = ?', (name, name.lower()))
+        if language:
+            return {
+                u'id': language[0][0],
+                u'name': unicode(language[0][1]),
+                u'code': unicode(language[0][2])
+            }
+        else:
+            return None
+
+    @staticmethod
+    def get_languages():
+        """
+        Return a dict containing all languages with id, name and code.
+        """
+        log.debug(u'BiblesResourcesDB.get_languages()')
+        languages = BiblesResourcesDB.run_sql(u'SELECT id, name, code FROM '
+                u'language ORDER by name')
+        if languages:
+            return [
+                {
+                u'id': language[0],
+                u'name': unicode(language[1]),
+                u'code': unicode(language[2])
+                }
+                for language in languages
+            ]
+        else:
+            return None
+
+    @staticmethod
+    def get_testament_reference():
+        """
+        Return a list of all testaments and their id of the Bible.
+        """
+        log.debug(u'BiblesResourcesDB.get_testament_reference()')
+        testaments = BiblesResourcesDB.run_sql(u'SELECT id, name FROM '
+                u'testament_reference ORDER BY id')
+        return [
+            {
+            u'id': testament[0],
+            u'name': unicode(testament[1])
+            }
+            for testament in testaments
+        ]
+
+
+class AlternativeBookNamesDB(QtCore.QObject, Manager):
+    """
+    This class represents a database-bound alternative book names system. 
+    """
+    cursor = None
+    conn = None
+
+    @staticmethod
+    def get_cursor():
+        """
+        Return the cursor object. Instantiate one if it doesn't exist yet.
+        If necessary loads up the database and creates the tables if the 
+        database doesn't exist.
+        """
+        if AlternativeBookNamesDB.cursor is None:
+            check_directory_exists(os.path.join(AppLocation.get_directory(
+                AppLocation.DataDir), u'bibles', u'resources'))
+            filepath = os.path.join(
+                AppLocation.get_directory(AppLocation.DataDir), u'bibles',
+                    u'resources', u'alternative_book_names.sqlite')
+            log.debug(u'Filepath: %s' % filepath)
+            if not os.path.exists(filepath):
+                #create new DB, create table alternative_book_names
+                AlternativeBookNamesDB.conn = sqlite3.connect(filepath)
+                AlternativeBookNamesDB.conn.execute(u'CREATE TABLE '
+                    u'alternative_book_names(id INTEGER NOT NULL, '
+                    u'book_reference_id INTEGER, language_id INTEGER, name '
+                    u'VARCHAR(50), PRIMARY KEY (id))')
+            else:
+                #use existing DB
+                AlternativeBookNamesDB.conn = sqlite3.connect(filepath)
+            AlternativeBookNamesDB.cursor = AlternativeBookNamesDB.conn.cursor()
+        return AlternativeBookNamesDB.cursor
+
+    @staticmethod
+    def run_sql(query, parameters=(), commit=None):
+        """
+        Run an SQL query on the database, returning the results.
+
+        ``query``
+            The actual SQL query to run.
+
+        ``parameters``
+            Any variable parameters to add to the query
+        
+        ``commit``
+            If a commit statement is necessary this should be True.
+        """
+        cursor = AlternativeBookNamesDB.get_cursor()
+        cursor.execute(query, parameters)
+        if commit:
+            AlternativeBookNamesDB.conn.commit()
+        return cursor.fetchall()
+
+    @staticmethod
+    def get_book_reference_id(name,  language_id=None):
+        """
+        Return a book_reference_id if the name matches.
+
+        ``name``
+            The name to search the id.
+            
+        ``language_id``
+            The language_id for which language should be searched
+        """
+        log.debug(u'AlternativeBookNamesDB.get_book_reference_id("%s", "%s")', 
+            name, language_id)
+        if language_id:
+            id = AlternativeBookNamesDB.run_sql(u'SELECT book_reference_id FROM'
+                u' alternative_book_names WHERE name = ? AND language_id = ?',
+                (name, language_id))
+        else:
+            id = AlternativeBookNamesDB.run_sql(u'SELECT book_reference_id FROM'
+                u' alternative_book_names WHERE name = ?', name)
+        if not id:
+            return None
+        else:
+            return id[0][0]
+
+    @staticmethod
+    def create_alternative_book_name(name, book_reference_id, language_id):
+        """
+        Add an alternative book name to the database.
+
+        ``name``
+            The name of the alternative book name.
+
+        ``book_reference_id``
+            The book_reference_id of the book.
+
+        ``language_id``
+            The language to which the alternative book name belong.
+        """
+        log.debug(u'AlternativeBookNamesDB.create_alternative_book_name("%s", '
+            '"%s", "%s"', name, book_reference_id, language_id)
+        return AlternativeBookNamesDB.run_sql(u'INSERT INTO '
+            u'alternative_book_names(book_reference_id, language_id, name) '
+            u'VALUES (?, ?, ?)', (book_reference_id, language_id, name), True)
+
+
+class OldBibleDB(QtCore.QObject, Manager):
+    """
+    This class conects to the old bible databases to reimport them to the new 
+    database scheme.
+    """
+    cursor = None
+    
+    def __init__(self, parent, **kwargs):
+        """
+        The constructor loads up the database and creates and initialises the
+        tables if the database doesn't exist.
+
+        **Required keyword arguments:**
+
+        ``path``
+            The path to the bible database file.
+
+        ``name``
+            The name of the database. This is also used as the file name for
+            SQLite databases.
+        """
+        log.info(u'OldBibleDB loaded')
+        QtCore.QObject.__init__(self)
+        if u'path' not in kwargs:
+            raise KeyError(u'Missing keyword argument "path".')
+        if  u'file' not in kwargs:
+            raise KeyError(u'Missing keyword argument "file".')
+        if u'path' in kwargs:
+            self.path = kwargs[u'path']
+        if u'file' in kwargs:
+            self.file = kwargs[u'file']
+
+    def get_cursor(self):
+        """
+        Return the cursor object. Instantiate one if it doesn't exist yet.
+        """
+        if self.cursor is None:
+            filepath = os.path.join(self.path, self.file)
+            conn = sqlite3.connect(filepath)
+            self.cursor = conn.cursor()
+        return self.cursor
+
+    def run_sql(self, query, parameters=()):
+        """
+        Run an SQL query on the database, returning the results.
+
+        ``query``
+            The actual SQL query to run.
+
+        ``parameters``
+            Any variable parameters to add to the query.
+        """
+        cursor = self.get_cursor()
+        cursor.execute(query, parameters)
+        return cursor.fetchall()
+
+    def get_name(self):
+        """
+        Returns the version name of the Bible.
+        """
+        version_name = self.run_sql(u'SELECT value FROM '
+                u'metadata WHERE key = "Version"')
+        if version_name:
+            self.name = version_name[0][0]
+        else:
+            self.name = None
+        return self.name
+
+    def get_metadata(self):
+        """
+        Returns the metadata of the Bible.
+        """
+        metadata = self.run_sql(u'SELECT key, value FROM metadata '
+            u'ORDER BY rowid')
+        if metadata:
+            return [
+                {
+                u'key': unicode(meta[0]),
+                u'value': unicode(meta[1])
+                }
+                for meta in metadata
+            ]
+        else:
+            return None
+
+    def get_books(self):
+        """
+        Returns the books of the Bible.
+        """
+        books = self.run_sql(u'SELECT name, id FROM book ORDER BY id')
+        if books:
+            return [
+                {
+                u'name': unicode(book[0]),
+                u'id':int(book[1])
+                }
+                for book in books
+            ]
+            book_list = []
+        else:
+            return None
+
+    def get_verses(self, book_id):
+        """
+        Returns the verses of the Bible.
+        """
+        verses = self.run_sql(u'SELECT book_id, chapter, verse, text FROM '
+            u'verse WHERE book_id = ? ORDER BY id', (book_id, ))
+        if verses:
+            return [
+                {
+                u'book_id': int(verse[0]),
+                u'chapter': int(verse[1]),
+                u'verse': int(verse[2]),
+                u'text': unicode(verse[3])
+                }
+                for verse in verses
+            ]
+        else:
+            return None

=== modified file 'openlp/plugins/bibles/lib/http.py'
--- openlp/plugins/bibles/lib/http.py	2011-03-24 19:04:02 +0000
+++ openlp/plugins/bibles/lib/http.py	2011-04-26 18:58:23 +0000
@@ -41,152 +41,17 @@
 from openlp.core.lib.ui import critical_error_message_box
 from openlp.core.utils import AppLocation, get_web_page
 from openlp.plugins.bibles.lib import SearchResults
-from openlp.plugins.bibles.lib.db import BibleDB, Book
+from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB, \
+    Book
 
 log = logging.getLogger(__name__)
 
-class HTTPBooks(object):
-    """
-    A wrapper class around a small SQLite database which contains the books,
-    chapter counts and verse counts for the web download Bibles. This class
-    contains a singleton "cursor" so that only one connection to the SQLite
-    database is ever used.
-    """
-    cursor = None
-
-    @staticmethod
-    def get_cursor():
-        """
-        Return the cursor object. Instantiate one if it doesn't exist yet.
-        """
-        if HTTPBooks.cursor is None:
-            filepath = os.path.join(
-                AppLocation.get_directory(AppLocation.PluginsDir), u'bibles',
-                u'resources', u'httpbooks.sqlite')
-            conn = sqlite3.connect(filepath)
-            HTTPBooks.cursor = conn.cursor()
-        return HTTPBooks.cursor
-
-    @staticmethod
-    def run_sql(query, parameters=()):
-        """
-        Run an SQL query on the database, returning the results.
-
-        ``query``
-            The actual SQL query to run.
-
-        ``parameters``
-            Any variable parameters to add to the query.
-        """
-        cursor = HTTPBooks.get_cursor()
-        cursor.execute(query, parameters)
-        return cursor.fetchall()
-
-    @staticmethod
-    def get_books():
-        """
-        Return a list of all the books of the Bible.
-        """
-        books = HTTPBooks.run_sql(u'SELECT id, testament_id, name, '
-                u'abbreviation, chapters FROM books ORDER BY id')
-        book_list = []
-        for book in books:
-            book_list.append({
-                u'id': book[0],
-                u'testament_id': book[1],
-                u'name': unicode(book[2]),
-                u'abbreviation': unicode(book[3]),
-                u'chapters': book[4]
-            })
-        return book_list
-
-    @staticmethod
-    def get_book(name):
-        """
-        Return a book by name or abbreviation.
-
-        ``name``
-            The name or abbreviation of the book.
-        """
-        if not isinstance(name, unicode):
-            name = unicode(name)
-        name = name.title()
-        books = HTTPBooks.run_sql(u'SELECT id, testament_id, name, '
-                u'abbreviation, chapters FROM books WHERE name = ? OR '
-                u'abbreviation = ?', (name, name))
-        if books:
-            return {
-                u'id': books[0][0],
-                u'testament_id': books[0][1],
-                u'name': unicode(books[0][2]),
-                u'abbreviation': unicode(books[0][3]),
-                u'chapters': books[0][4]
-            }
-        else:
-            return None
-
-    @staticmethod
-    def get_chapter(name, chapter):
-        """
-        Return the chapter details for a specific chapter of a book.
-
-        ``name``
-            The name or abbreviation of a book.
-
-        ``chapter``
-            The chapter number.
-        """
-        if not isinstance(name, int):
-            chapter = int(chapter)
-        book = HTTPBooks.get_book(name)
-        chapters = HTTPBooks.run_sql(u'SELECT id, book_id, chapter, '
-            u'verses FROM chapters WHERE book_id = ?', (book[u'id'],))
-        if chapters:
-            return {
-                u'id': chapters[chapter-1][0],
-                u'book_id': chapters[chapter-1][1],
-                u'chapter': chapters[chapter-1][2],
-                u'verses': chapters[chapter-1][3]
-            }
-        else:
-            return None
-
-    @staticmethod
-    def get_chapter_count(book):
-        """
-        Return the number of chapters in a book.
-
-        ``book``
-            The name or abbreviation of the book.
-        """
-        details = HTTPBooks.get_book(book)
-        if details:
-            return details[u'chapters']
-        return 0
-
-    @staticmethod
-    def get_verse_count(book, chapter):
-        """
-        Return the number of verses in a chapter.
-
-        ``book``
-            The name or abbreviation of the book.
-
-        ``chapter``
-            The number of the chapter.
-        """
-        details = HTTPBooks.get_chapter(book, chapter)
-        if details:
-            return details[u'verses']
-        return 0
-
-
 class BGExtract(object):
     """
     Extract verses from BibleGateway
     """
     def __init__(self, proxyurl=None):
-        log.debug(u'init %s', proxyurl)
+        log.debug(u'BGExtract.init("%s")', proxyurl)
         self.proxyurl = proxyurl
         socket.setdefaulttimeout(30)
 
@@ -203,9 +68,11 @@
         ``chapter``
             Chapter number.
         """
-        log.debug(u'get_bible_chapter %s, %s, %s', version, bookname, chapter)
+        log.debug(u'BGExtract.get_bible_chapter("%s", "%s", "%s")', version, 
+            bookname, chapter)
+        urlbookname = urllib.quote(bookname.encode("utf-8"))
         url_params = urllib.urlencode(
-            {u'search': u'%s %s' % (bookname, chapter),
+            {u'search': u'%s %s' % (urlbookname, chapter),
             u'version': u'%s' % version})
         cleaner = [(re.compile('&nbsp;|<br />|\'\+\''), lambda match: '')]
         soup = get_soup_for_bible_ref(
@@ -263,13 +130,57 @@
             return None
         return SearchResults(bookname, chapter, verse_list)
 
+    def get_books_from_http(self, version):
+        """
+        Load a list of all books a bible contaions from BibleGateway website.
+
+        ``version``
+            The version of the bible like NIV for New International Version
+        """
+        log.debug(u'BGExtract.get_books_from_http("%s")', version)
+        url_params = urllib.urlencode(
+            {u'search': 'Bible-List', u'version': u'%s' % version})
+        reference_url = u'http://www.biblegateway.com/passage/?%s' % url_params
+        page = get_web_page(reference_url)
+        if not page:
+            send_error_message(u'download')
+            return None
+        page_source = page.read()
+        page_source = unicode(page_source, 'utf8')
+        page_source_temp = re.search(u'<table id="booklist".*?>.*?</table>', \
+            page_source, re.DOTALL)
+        if page_source_temp:
+            soup = page_source_temp.group(0)
+        else:
+            soup = None
+        try:
+            soup = BeautifulSoup(soup)
+        except HTMLParseError:
+            log.exception(u'BeautifulSoup could not parse the bible page.')
+        if not soup:
+            send_error_message(u'parse')
+            return None
+        Receiver.send_message(u'openlp_process_events')
+        content = soup.find(u'table', {u'id': u'booklist'})
+        content = content.findAll(u'tr')
+        if not content:
+            log.exception(u'No books found in the Biblegateway response.')
+            send_error_message(u'parse')
+            return None
+        books = []
+        for book in content:
+            book = book.find(u'td')
+            if book:
+                books.append(book.contents[0])
+        return books
+
 
 class BSExtract(object):
     """
     Extract verses from Bibleserver.com
     """
     def __init__(self, proxyurl=None):
-        log.debug(u'init %s', proxyurl)
+        log.debug(u'BSExtract.init("%s")', proxyurl)
         self.proxyurl = proxyurl
         socket.setdefaulttimeout(30)
 
@@ -286,9 +197,11 @@
         ``chapter``
             Chapter number
         """
-        log.debug(u'get_bible_chapter %s,%s,%s', version, bookname, chapter)
+        log.debug(u'BSExtract.get_bible_chapter("%s", "%s", "%s")', version, 
+            bookname, chapter)
+        urlbookname = urllib.quote(bookname.encode("utf-8"))
         chapter_url = u'http://m.bibleserver.com/text/%s/%s%s' % \
-            (version, bookname, chapter)
+            (version, urlbookname, chapter)
         header = (u'Accept-Language', u'en')
         soup = get_soup_for_bible_ref(chapter_url, header)
         if not soup:
@@ -308,13 +221,37 @@
             verses[versenumber] = verse.contents[1].rstrip(u'\n')
         return SearchResults(bookname, chapter, verses)
 
+    def get_books_from_http(self, version):
+        """
+        Load a list of all books a bible contains from Bibleserver mobile 
+        website.
+
+        ``version``
+            The version of the bible like NIV for New International Version
+        """
+        log.debug(u'BSExtract.get_books_from_http("%s")', version)
+        chapter_url = u'http://m.bibleserver.com/overlay/selectBook?'\
+            'translation=%s' % (version)
+        soup = get_soup_for_bible_ref(chapter_url)
+        if not soup:
+            return None
+        content = soup.find(u'ul')
+        if not content:
+            log.exception(u'No books found in the Bibleserver response.')
+            send_error_message(u'parse')
+            return None
+        content = content.findAll(u'li')
+        return [
+            book.contents[0].contents[0] for book in content
+        ]
+
 
 class CWExtract(object):
     """
     Extract verses from CrossWalk/BibleStudyTools
     """
     def __init__(self, proxyurl=None):
-        log.debug(u'init %s', proxyurl)
+        log.debug(u'CWExtract.init("%s")', proxyurl)
         self.proxyurl = proxyurl
         socket.setdefaulttimeout(30)
 
@@ -331,10 +268,13 @@
         ``chapter``
             Chapter number
         """
-        log.debug(u'get_bible_chapter %s,%s,%s', version, bookname, chapter)
+        log.debug(u'CWExtract.get_bible_chapter("%s", "%s", "%s")', version, 
+            bookname, chapter)
         urlbookname = bookname.replace(u' ', u'-')
+        urlbookname = urlbookname.lower()
+        urlbookname = urllib.quote(urlbookname.encode("utf-8"))
         chapter_url = u'http://www.biblestudytools.com/%s/%s/%s.html' % \
-            (version, urlbookname.lower(), chapter)
+            (version, urlbookname, chapter)
         soup = get_soup_for_bible_ref(chapter_url)
         if not soup:
             return None
@@ -377,6 +317,32 @@
             verses[versenumber] = versetext
         return SearchResults(bookname, chapter, verses)
 
+    def get_books_from_http(self, version):
+        """
+        Load a list of all books  a bible contain from the Crosswalk website.
+
+        ``version``
+            The version of the bible like NIV for New International Version
+        """
+        log.debug(u'CWExtract.get_books_from_http("%s")', version)
+        chapter_url = u'http://www.biblestudytools.com/%s/'\
+             % (version)
+        soup = get_soup_for_bible_ref(chapter_url)
+        if not soup:
+            return None
+        content = soup.find(u'div', {u'class': u'Body'})
+        content = content.find(u'ul', {u'class': u'parent'})
+        if not content:
+            log.exception(u'No books found in the Crosswalk response.')
+            send_error_message(u'parse')
+            return None
+        content = content.findAll(u'li')
+        books = []
+        for book in content:
+            book = book.find(u'a')
+            books.append(book.contents[0])
+        return books
+
 
 class HTTPBible(BibleDB):
     log.info(u'%s HTTPBible loaded' , __name__)
@@ -399,6 +365,8 @@
         self.proxy_server = None
         self.proxy_username = None
         self.proxy_password = None
+        if u'path' in kwargs:
+            self.path = kwargs[u'path']
         if u'proxy_server' in kwargs:
             self.proxy_server = kwargs[u'proxy_server']
         if u'proxy_username' in kwargs:
@@ -411,8 +379,10 @@
         Run the import. This method overrides the parent class method. Returns
         ``True`` on success, ``False`` on failure.
         """
-        self.wizard.progressBar.setMaximum(2)
-        self.wizard.incrementProgressBar('Registering bible...')
+        self.wizard.progressBar.setMaximum(68)
+        self.wizard.incrementProgressBar(unicode(translate(
+            'BiblesPlugin.HTTPBible', 
+            'Registering bible and loading books...')))
         self.create_meta(u'download source', self.download_source)
         self.create_meta(u'download name', self.download_name)
         if self.proxy_server:
@@ -423,6 +393,44 @@
         if self.proxy_password:
             # Store the proxy password.
             self.create_meta(u'proxy password', self.proxy_password)
+        if self.download_source.lower() == u'crosswalk':
+            handler = CWExtract(self.proxy_server)
+        elif self.download_source.lower() == u'biblegateway':
+            handler = BGExtract(self.proxy_server)
+        elif self.download_source.lower() == u'bibleserver':
+            handler = BSExtract(self.proxy_server)
+        books = handler.get_books_from_http(self.download_name)
+        if not books:
+            log.exception(u'Importing books from %s - download name: "%s" '\
+                'failed' % (self.download_source,  self.download_name))
+            return False
+        self.wizard.progressBar.setMaximum(len(books)+2)
+        self.wizard.incrementProgressBar(unicode(translate(
+            'BiblesPlugin.HTTPBible', 'Registering Language...')))
+        bible = BiblesResourcesDB.get_webbible(self.download_name, 
+                self.download_source.lower())
+        if bible[u'language_id']:
+            language_id = bible[u'language_id']
+            self.create_meta(u'language_id', language_id)
+        else:
+            language_id = self.get_language()
+        if not language_id:
+            log.exception(u'Importing books from %s   " '\
+                'failed' % self.filename)
+            return False
+        for book in books:
+            self.wizard.incrementProgressBar(unicode(translate(
+                            'BiblesPlugin.HTTPBible', 'Importing %s...',
+                            'Importing <book name>...')) % book)
+            book_ref_id = self.get_book_ref_id_by_name(book, language_id)
+            if not book_ref_id:
+                log.exception(u'Importing books from %s - download name: "%s" '\
+                    'failed' % (self.download_source,  self.download_name))
+                return False
+            book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
+            log.debug(u'Book details: Name:%s; id:%s; testament_id:%s', 
+                book, book_ref_id, book_details[u'testament_id'])
+            self.create_book(book, book_ref_id, book_details[u'testament_id'])
         return True
 
     def get_verses(self, reference_list):
@@ -437,33 +445,28 @@
             This is the list of references the media manager item wants. It is
             a list of tuples, with the following format::
 
-                (book, chapter, start_verse, end_verse)
+                (book_reference_id, chapter, start_verse, end_verse)
 
             Therefore, when you are looking for multiple items, simply break
             them up into references like this, bundle them into a list. This
             function then runs through the list, and returns an amalgamated
             list of ``Verse`` objects. For example::
 
-                [(u'Genesis', 1, 1, 1), (u'Genesis', 2, 2, 3)]
+                [(u'35', 1, 1, 1), (u'35', 2, 2, 3)]
         """
+        log.debug(u'HTTPBible.get_verses("%s")', reference_list)
         for reference in reference_list:
-            log.debug(u'Reference: %s', reference)
-            book = reference[0]
-            db_book = self.get_book(book)
+            book_id = reference[0]
+            db_book = self.get_book_by_book_ref_id(book_id)
             if not db_book:
-                book_details = HTTPBooks.get_book(book)
-                if not book_details:
-                    critical_error_message_box(
-                        translate('BiblesPlugin', 'No Book Found'),
-                        translate('BiblesPlugin', 'No matching '
-                        'book could be found in this Bible. Check that you '
-                        'have spelled the name of the book correctly.'))
-                    return []
-                db_book = self.create_book(book_details[u'name'],
-                    book_details[u'abbreviation'],
-                    book_details[u'testament_id'])
+                critical_error_message_box(
+                    translate('BiblesPlugin', 'No Book Found'),
+                    translate('BiblesPlugin', 'No matching '
+                    'book could be found in this Bible. Check that you '
+                    'have spelled the name of the book correctly.'))
+                return []
             book = db_book.name
-            if BibleDB.get_verse_count(self, book, reference[1]) == 0:
+            if BibleDB.get_verse_count(self, book_id, reference[1]) == 0:
                 Receiver.send_message(u'cursor_busy')
                 search_results = self.get_chapter(book, reference[1])
                 if search_results and search_results.has_verselist():
@@ -486,7 +489,7 @@
         """
         Receive the request and call the relevant handler methods.
         """
-        log.debug(u'get_chapter %s, %s', book, chapter)
+        log.debug(u'HTTPBible.get_chapter("%s", "%s")', book, chapter)
         log.debug(u'source = %s', self.download_source)
         if self.download_source.lower() == u'crosswalk':
             handler = CWExtract(self.proxy_server)
@@ -500,16 +503,20 @@
         """
         Return the list of books.
         """
-        return [Book.populate(name=book['name'])
-            for book in HTTPBooks.get_books()]
+        log.debug(u'HTTPBible.get_books("%s")', Book.name)
+        return self.get_all_objects(Book, order_by_ref=Book.id)
 
     def get_chapter_count(self, book):
         """
         Return the number of chapters in a particular book.
+        
+        ``book``
+        The book object to get the chapter count for.
         """
-        return HTTPBooks.get_chapter_count(book)
+        log.debug(u'HTTPBible.get_chapter_count("%s")', book.name)
+        return BiblesResourcesDB.get_chapter_count(book.book_reference_id)
 
-    def get_verse_count(self, book, chapter):
+    def get_verse_count(self, book_id, chapter):
         """
         Return the number of verses for the specified chapter and book.
 
@@ -519,7 +526,8 @@
         ``chapter``
             The chapter whose verses are being counted.
         """
-        return HTTPBooks.get_verse_count(book, chapter)
+        log.debug(u'HTTPBible.get_verse_count("%s", %s)', book_id, chapter)
+        return BiblesResourcesDB.get_verse_count(book_id, chapter)
 
 def get_soup_for_bible_ref(reference_url, header=None, pre_parse_regex=None,
     pre_parse_substitute=None, cleaner=None):

=== modified file 'openlp/plugins/bibles/lib/manager.py'
--- openlp/plugins/bibles/lib/manager.py	2011-03-24 19:04:02 +0000
+++ openlp/plugins/bibles/lib/manager.py	2011-04-26 18:58:23 +0000
@@ -30,6 +30,7 @@
 from PyQt4 import QtCore
 
 from openlp.core.lib import Receiver, SettingsManager, translate
+from openlp.core.lib.ui import critical_error_message_box
 from openlp.core.utils import AppLocation, delete_file
 from openlp.plugins.bibles.lib import parse_reference
 from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta
@@ -119,7 +120,7 @@
         """
         log.debug(u'Bible Initialising')
         self.parent = parent
-        self.settingsSection = u'bibles'
+        self.settingsSection = u'bibles/bibles'
         self.web = u'Web'
         self.db_cache = None
         self.path = AppLocation.get_section_data_path(self.settingsSection)
@@ -209,8 +210,9 @@
         log.debug(u'BibleManager.get_books("%s")', bible)
         return [
             {
-                u'name': book.name,
-                u'chapters': self.db_cache[bible].get_chapter_count(book.name)
+            u'name': book.name,
+            u'chapters': self.db_cache[bible].get_chapter_count(
+                book)
             }
             for book in self.db_cache[bible].get_books()
         ]
@@ -218,8 +220,15 @@
     def get_chapter_count(self, bible, book):
         """
         Returns the number of Chapters for a given book.
+        
+        ``bible``
+            Unicode. The Bible to get the list of books from.
+        
+        ``book``
+            The book object to get the chapter count for.
         """
-        log.debug(u'get_book_chapter_count %s', book)
+        log.debug(u'BibleManager.get_book_chapter_count ("%s", "%s")', bible,
+            book.name)
         return self.db_cache[bible].get_chapter_count(book)
 
     def get_verse_count(self, bible, book, chapter):
@@ -229,9 +238,11 @@
         """
         log.debug(u'BibleManager.get_verse_count("%s", "%s", %s)',
             bible, book, chapter)
-        return self.db_cache[bible].get_verse_count(book, chapter)
+        db_book = self.db_cache[bible].get_book(book)
+        book_ref_id = db_book.book_reference_id
+        return self.db_cache[bible].get_verse_count(book_ref_id, chapter)
 
-    def get_verses(self, bible, versetext):
+    def get_verses(self, bible, versetext, firstbible=False):
         """
         Parses a scripture reference, fetches the verses from the Bible
         specified, and returns a list of ``Verse`` objects.
@@ -262,6 +273,28 @@
             return None
         reflist = parse_reference(versetext)
         if reflist:
+            new_reflist = []
+            for item in reflist:
+                if item:
+                    if firstbible:
+                        db_book = self.db_cache[firstbible].get_book(item[0])
+                        db_book = self.db_cache[bible].get_book_by_book_ref_id(
+                            db_book.book_reference_id)
+                    else:
+                        db_book = self.db_cache[bible].get_book(item[0])
+                    if db_book:
+                        book_id = db_book.book_reference_id
+                        log.debug(u'Book name corrected to "%s"', db_book.name)
+                        new_reflist.append((book_id, item[1], item[2], 
+                            item[3]))
+                    else:
+                        log.debug(u'OpenLP failed to find book %s', item[0])
+                        critical_error_message_box(
+                            translate('BiblesPlugin', 'No Book Found'),
+                            translate('BiblesPlugin', 'No matching book '
+                            'could be found in this Bible. Check that you have '
+                            'spelled the name of the book correctly.'))
+            reflist = new_reflist
             return self.db_cache[bible].get_verses(reflist)
         else:
             Receiver.send_message(u'openlp_information_message', {

=== modified file 'openlp/plugins/bibles/lib/mediaitem.py'
--- openlp/plugins/bibles/lib/mediaitem.py	2011-04-15 21:43:59 +0000
+++ openlp/plugins/bibles/lib/mediaitem.py	2011-04-26 18:58:23 +0000
@@ -514,7 +514,7 @@
         self.search_results = self.parent.manager.get_verses(bible, versetext)
         if second_bible:
             self.second_search_results = self.parent.manager.get_verses(
-                second_bible, versetext)
+                second_bible, versetext, bible)
         if self.advancedClearComboBox.currentIndex() == 0:
             self.listView.clear()
         if self.listView.count() != 0:
@@ -541,7 +541,7 @@
             self.search_results = self.parent.manager.get_verses(bible, text)
             if second_bible and self.search_results:
                 self.second_search_results = self.parent.manager.get_verses(
-                    second_bible, text)
+                    second_bible, text, bible)
         else:
             # We are doing a 'Text Search'.
             Receiver.send_message(u'cursor_busy')
@@ -849,4 +849,4 @@
             self.settings.layout_style)
         QtCore.QSettings().setValue(
             self.settingsSection + u'/verse layout style',
-            QtCore.QVariant(self.settings.layout_style))
\ No newline at end of file
+            QtCore.QVariant(self.settings.layout_style))

=== modified file 'openlp/plugins/bibles/lib/openlp1.py'
--- openlp/plugins/bibles/lib/openlp1.py	2011-03-24 19:04:02 +0000
+++ openlp/plugins/bibles/lib/openlp1.py	2011-04-26 18:58:23 +0000
@@ -29,7 +29,7 @@
 
 from openlp.core.lib import Receiver
 from openlp.core.ui.wizard import WizardStrings
-from openlp.plugins.bibles.lib.db import BibleDB
+from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
 
 log = logging.getLogger(__name__)
 
@@ -56,6 +56,12 @@
             cursor = connection.cursor()
         except:
             return False
+        #Create the bible language
+        language_id = self.get_language()
+        if not language_id:
+            log.exception(u'Importing books from "%s " '\
+                'failed' % self.filename)
+            return False
         # Create all books.
         cursor.execute(u'SELECT id, testament_id, name, abbreviation FROM book')
         books = cursor.fetchall()
@@ -68,7 +74,14 @@
             testament_id = int(book[1])
             name = unicode(book[2], u'cp1252')
             abbreviation = unicode(book[3], u'cp1252')
-            self.create_book(name, abbreviation, testament_id)
+            book_ref_id = self.get_book_ref_id_by_name(name, language_id)
+            if not book_ref_id:
+                log.exception(u'Importing books from "%s" '\
+                    'failed' % self.filename)
+                return False
+            book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
+            db_book = self.create_book(name, book_ref_id, 
+                book_details[u'testament_id'])
             # Update the progess bar.
             self.wizard.incrementProgressBar(WizardStrings.ImportingType % name)
             # Import the verses for this book.
@@ -82,7 +95,7 @@
                 chapter = int(verse[0])
                 verse_number = int(verse[1])
                 text = unicode(verse[2], u'cp1252')
-                self.create_verse(book_id, chapter, verse_number, text)
+                self.create_verse(db_book.id, chapter, verse_number, text)
                 Receiver.send_message(u'openlp_process_events')
             self.session.commit()
         connection.close()

=== modified file 'openlp/plugins/bibles/lib/opensong.py'
--- openlp/plugins/bibles/lib/opensong.py	2011-03-24 19:04:02 +0000
+++ openlp/plugins/bibles/lib/opensong.py	2011-04-26 18:58:23 +0000
@@ -28,7 +28,7 @@
 from lxml import objectify
 
 from openlp.core.lib import Receiver, translate
-from openlp.plugins.bibles.lib.db import BibleDB
+from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
 
 log = logging.getLogger(__name__)
 
@@ -61,11 +61,23 @@
             file = open(self.filename, u'r')
             opensong = objectify.parse(file)
             bible = opensong.getroot()
+            language_id = self.get_language()
+            if not language_id:
+                log.exception(u'Importing books from "%s" '\
+                    'failed' % self.filename)
+                return False
             for book in bible.b:
                 if self.stop_import_flag:
                     break
-                db_book = self.create_book(unicode(book.attrib[u'n']),
-                    unicode(book.attrib[u'n'][:4]))
+                book_ref_id = self.get_book_ref_id_by_name(
+                    unicode(book.attrib[u'n']), language_id)
+                if not book_ref_id:
+                    log.exception(u'Importing books from "%s" '\
+                        'failed' % self.filename)
+                    return False
+                book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
+                db_book = self.create_book(unicode(book.attrib[u'n']), 
+                    book_ref_id, book_details[u'testament_id'])
                 for chapter in book.c:
                     if self.stop_import_flag:
                         break

=== modified file 'openlp/plugins/bibles/lib/osis.py'
--- openlp/plugins/bibles/lib/osis.py	2011-03-24 19:04:02 +0000
+++ openlp/plugins/bibles/lib/osis.py	2011-04-26 18:58:23 +0000
@@ -33,7 +33,7 @@
 
 from openlp.core.lib import Receiver, translate
 from openlp.core.utils import AppLocation
-from openlp.plugins.bibles.lib.db import BibleDB
+from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
 
 log = logging.getLogger(__name__)
 
@@ -91,7 +91,6 @@
         osis = None
         success = True
         last_chapter = 0
-        testament = 1
         match_count = 0
         self.wizard.incrementProgressBar(translate('BiblesPlugin.OsisImport',
             'Detecting encoding (this may take a few minutes)...'))
@@ -104,6 +103,12 @@
         finally:
             if detect_file:
                 detect_file.close()
+        # Set meta language_id
+        language_id = self.get_language()
+        if not language_id:
+            log.exception(u'Importing books from "%s" '\
+                'failed' % self.filename)
+            return False
         try:
             osis = codecs.open(self.filename, u'r', details['encoding'])
             for file_record in osis:
@@ -117,13 +122,19 @@
                     verse = int(match.group(3))
                     verse_text = match.group(4)
                     if not db_book or db_book.name != self.books[book][0]:
-                        log.debug(u'New book: "%s"', self.books[book][0])
-                        if book == u'Matt' or book == u'Jdt':
-                            testament += 1
+                        log.debug(u'New book: "%s"' % self.books[book][0])
+                        book_ref_id = self.get_book_ref_id_by_name(
+                            unicode(self.books[book][0]), language_id)
+                        if not book_ref_id:
+                            log.exception(u'Importing books from "%s" '\
+                                'failed' % self.filename)
+                            return False
+                        book_details = BiblesResourcesDB.get_book_by_id(
+                            book_ref_id)
                         db_book = self.create_book(
                             unicode(self.books[book][0]),
-                            unicode(self.books[book][1]),
-                            testament)
+                            book_ref_id,
+                            book_details[u'testament_id'])
                     if last_chapter == 0:
                         if book == u'Gen':
                             self.wizard.progressBar.setMaximum(1188)

=== removed file 'openlp/plugins/bibles/resources/biblegateway.csv'
--- openlp/plugins/bibles/resources/biblegateway.csv	2010-12-17 22:10:29 +0000
+++ openlp/plugins/bibles/resources/biblegateway.csv	1970-01-01 00:00:00 +0000
@@ -1,81 +0,0 @@
-João Ferreira de Almeida Atualizada,AA
-التفسير التطبيقى للكتاب المقدس,ALAB
-Shqip,ALB
-Amplified Bible,AMP
-Amuzgo de Guerrero,AMU
-American Standard Version,ASV
-La Bible du Semeur,BDS
-Български 1940,BG1940
-Български,BULG
-Chinanteco de Comaltepec,CCO
-Contemporary English Version,CEV
-Cakchiquel Occidental,CKW
-Hrvatski,CRO
-Castilian,CST
-聖經和合本 (简体中文),CUVS
-聖經和合本 (繁体中文),CUV
-Darby Translation,DARBY
-Dette er Biblen på dansk,DN1933
-Det Norsk Bibelselskap 1930,DNB1930
-English Standard Version,ESV
-GOD’S WORD Translation,GW
-Holman Christian Standard Bible,HCSB
-Kreyòl ayisyen bib,HCV
-Hiligaynon Bible,HLGN
-Hoffnung für Alle,HOF
-Het Boek,HTB
-Icelandic Bible,ICELAND
-Jacalteco – Oriental,JAC
-Károlyi-biblia,KAR
-Kekchi,KEK
-21st Century King James Version,KJ21
-King James Version,KJV
-La Biblia de las Américas,LBLA
-Levande Bibeln,LB
-La Parola è Vita,LM
-La Nuova Diodati,LND
-Louis Segond,LSG
-Luther Bibel 1545,LUTH1545
-Māori Bible,MAORI
-Македонски Новиот Завет,MNT
-The Message,MSG
-Mam de Comitancillo Central,MVC
-Mam de Todos Santos Cuchumatán,MVJ
-New American Standard Bible,NASB
-New Century Version,NCV
-Náhuatl de Guerrero,NGU
-New International Reader's Version,NIRV
-New International Version 1984,NIV1984
-New International Version 2010,NIV
-New International Version - UK,NIVUK
-New King James Version,NKJV
-New Living Translation,NLT
-Nádej pre kazdého,NPK
-Nueva Versión Internacional,NVI
-O Livro,OL
-Quiché – Centro Occidental,QUT
-Reimer 2001,REIMER
-Română Cornilescu,RMNN
-Новый перевод на русский язык,RUSV
-Reina-Valera Antigua,RVA
-Reina-Valera 1960,RVR1960
-Reina-Valera 1995,RVR1995
-Slovo na cestu,SNC
-Ang Salita ng Diyos,SND
-Swahili New Testament,SNT
-Svenska 1917,SV1917
-Levande Bibeln,SVL
-Создать страницу,SZ
-Traducción en lenguaje actual,TLA
-New Romanian Translation,TLCR
-Today’s New International Version 2005,TNIV
-Textus Receptus Stephanus 1550,TR1550
-Textus Receptus Scrivener 1894,TR1894
-Українська Біблія. Переклад Івана Огієнка,UKR
-Uspanteco,USP
-Kinh Thánh tiếng Việt 1934,VIET
-Worldwide English (New Testament),WE
-Codex Vaticanus Westcott-Hort 1881,WHNU
-Westminster Leningrad Codex,WLC
-Wycliffe New Testament,WYC
-Young's Literal Translation,YLT

=== added file 'openlp/plugins/bibles/resources/bibles_resources.sqlite'
Binary files openlp/plugins/bibles/resources/bibles_resources.sqlite	1970-01-01 00:00:00 +0000 and openlp/plugins/bibles/resources/bibles_resources.sqlite	2011-04-26 18:58:23 +0000 differ
=== removed file 'openlp/plugins/bibles/resources/bibleserver.csv'
--- openlp/plugins/bibles/resources/bibleserver.csv	2011-01-25 01:19:57 +0000
+++ openlp/plugins/bibles/resources/bibleserver.csv	1970-01-01 00:00:00 +0000
@@ -1,39 +0,0 @@
-عربي, ARA
-Bible – překlad 21. století, B21
-Bible du Semeur, BDS
-Българската Библия, BLG
-Český ekumenický překlad, CEP
-Hrvatski, CRO
-Священное Писание, CRS
-Version La Biblia al Dia, CST
-中文和合本(简体), CUVS
-Bibelen på hverdagsdansk, DK
-Revidierte Elberfelder, ELB
-Einheitsübersetzung, EU
-Gute Nachricht Bibel, GNB
-Hoffnung für alle, HFA
-Hungarian, HUN
-Het Boek, HTB
-La Parola è Vita, ITA
-IBS-fordítás (Új Károli), KAR
-King James Version, KJV
-Luther 1984, LUT
-Septuaginta, LXX
-Neue Genfer Ãœbersetzung, NGU
-New International Readers Version, NIRV
-New International Version, NIV
-Neues Leben, NL
-En Levende Bok (NOR), NOR
-Nádej pre kazdého, NPK
-Noua traducere în limba românã, NTR
-Nueva Versión Internacional, NVI
-הברית הישנה, OT
-Słowo Życia, POL
-O Livro, PRT
-Новый перевод на русский язык, RUS
-Slovo na cestu, SNC
-Schlachter 2000, SLT
-En Levande Bok (SWE), SVL
-Today's New International Version, TNIV
-Türkçe, TR
-Biblia Vulgata, VUL

=== removed file 'openlp/plugins/bibles/resources/crosswalkbooks.csv'
--- openlp/plugins/bibles/resources/crosswalkbooks.csv	2010-12-17 22:10:29 +0000
+++ openlp/plugins/bibles/resources/crosswalkbooks.csv	1970-01-01 00:00:00 +0000
@@ -1,27 +0,0 @@
-New American Standard,nas
-American Standard Version,asv
-English Standard Version,esv
-New King James Version,nkj
-King James Version,kjv
-Holman Christian Standard Bible,csb
-Third Millennium Bible,tmb
-New International Version,niv
-New Living Translation,nlt
-New Revised Standard,nrs
-Revised Standard Version,rsv
-Good News Translation,gnt
-Douay-Rheims Bible,rhe
-The Message,msg
-The Complete Jewish Bible,cjb
-New Century Version,ncv
-GOD'S WORD Translation,gwd
-Hebrew Names Version,hnv
-World English Bible,web
-The Bible in Basic English,bbe
-Young's Literal Translation,ylt
-Today's New International Version,tnv
-New International Reader's Version,nrv
-The Darby Translation,dby
-The Webster Bible,wbt
-The Latin Vulgate,vul
-Weymouth New Testament,wnt

=== removed file 'openlp/plugins/bibles/resources/httpbooks.sqlite'
Binary files openlp/plugins/bibles/resources/httpbooks.sqlite	2011-01-22 17:35:02 +0000 and openlp/plugins/bibles/resources/httpbooks.sqlite	1970-01-01 00:00:00 +0000 differ
=== added file 'resources/images/bibles_upgrade_alert.png'
Binary files resources/images/bibles_upgrade_alert.png	1970-01-01 00:00:00 +0000 and resources/images/bibles_upgrade_alert.png	2011-04-26 18:58:23 +0000 differ
=== modified file 'resources/images/openlp-2.qrc'
--- resources/images/openlp-2.qrc	2011-03-09 16:16:40 +0000
+++ resources/images/openlp-2.qrc	2011-04-26 18:58:23 +0000
@@ -24,6 +24,7 @@
   <qresource prefix="bibles">
     <file>bibles_search_text.png</file>
     <file>bibles_search_reference.png</file>
+    <file>bibles_upgrade_alert.png</file>
   </qresource>
   <qresource prefix="plugins">
     <file>plugin_alerts.png</file>


Follow ups