diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py
index 8c62304f09..df6ac45e5b 100644
--- a/src/calibre/gui2/__init__.py
+++ b/src/calibre/gui2/__init__.py
@@ -54,7 +54,7 @@ gprefs.defaults['toolbar_text'] = 'auto'
gprefs.defaults['show_child_bar'] = False
gprefs.defaults['font'] = None
gprefs.defaults['tags_browser_partition_method'] = 'first letter'
-gprefs.defaults['tags_browser_collapse_at'] = 50
+gprefs.defaults['tags_browser_collapse_at'] = 100
# }}}
diff --git a/src/calibre/gui2/convert/gui_conversion.py b/src/calibre/gui2/convert/gui_conversion.py
index 116f09e429..d1e1270924 100644
--- a/src/calibre/gui2/convert/gui_conversion.py
+++ b/src/calibre/gui2/convert/gui_conversion.py
@@ -30,7 +30,7 @@ def gui_catalog(fmt, title, dbspec, ids, out_file_name, sync, fmt_options, conne
from calibre.library import db
from calibre.utils.config import prefs
prefs.refresh()
- db = db()
+ db = db(read_only=True)
db.catalog_plugin_on_device_temp_mapping = dbspec
# Create a minimal OptionParser that we can append to
diff --git a/src/calibre/gui2/preferences/look_feel.ui b/src/calibre/gui2/preferences/look_feel.ui
index 36a45b8dce..3b6bbb63ab 100644
--- a/src/calibre/gui2/preferences/look_feel.ui
+++ b/src/calibre/gui2/preferences/look_feel.ui
@@ -7,7 +7,7 @@
0
0
670
- 420
+ 392
@@ -141,35 +141,63 @@
- -
-
-
- Tags browser: partitioning method:
-
-
- opt_tags_browser_partition_method
-
-
-
- -
-
-
- -
-
-
- Tags browser - collapse when more items than:
-
-
- opt_tags_browser_collapse_at
-
-
-
- -
-
-
- 1000000
-
-
+
-
+
+
-
+
+
+ Tags browser category partitioning method:
+
+
+ opt_tags_browser_partition_method
+
+
+
+ -
+
+
+ Choose how tag browser subcategories are displayed when
+there are more items than the limit. Select by first
+letter to see an A, B, C list. Choose partitioned to
+have a list of fixed-sized groups. Set to disabled
+if you never want subcategories
+
+
+
+ -
+
+
+ Collapse when more items than:
+
+
+ opt_tags_browser_collapse_at
+
+
+
+ -
+
+
+ If a Tag Browser category has more than this number of items, it is divided up into sub-categories. Set to zero to disable.
+
+
+ 10000
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 20
+ 5
+
+
+
+
+
-
diff --git a/src/calibre/gui2/wizard/__init__.py b/src/calibre/gui2/wizard/__init__.py
index 4f418d34d5..4e5e79bbdf 100644
--- a/src/calibre/gui2/wizard/__init__.py
+++ b/src/calibre/gui2/wizard/__init__.py
@@ -174,7 +174,7 @@ class CybookOrizon(CybookOpus):
class PocketBook360(CybookOpus):
manufacturer = 'PocketBook'
- name = 'PocketBook 360'
+ name = 'PocketBook 360 and newer models'
id = 'pocketbook360'
output_profile = 'cybook_opus'
diff --git a/src/calibre/library/__init__.py b/src/calibre/library/__init__.py
index d08ca0b44f..2e00db32c4 100644
--- a/src/calibre/library/__init__.py
+++ b/src/calibre/library/__init__.py
@@ -2,10 +2,11 @@ __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal '
''' Code to manage ebook library'''
-def db(path=None):
+def db(path=None, read_only=False):
from calibre.library.database2 import LibraryDatabase2
from calibre.utils.config import prefs
- return LibraryDatabase2(path if path else prefs['library_path'])
+ return LibraryDatabase2(path if path else prefs['library_path'],
+ read_only=read_only)
def generate_test_db(library_path, # {{{
diff --git a/src/calibre/library/catalog.py b/src/calibre/library/catalog.py
index f21f4278a4..6b34b7f08c 100644
--- a/src/calibre/library/catalog.py
+++ b/src/calibre/library/catalog.py
@@ -1005,7 +1005,6 @@ class EPUB_MOBI(CatalogPlugin):
self.opts.log.warning(" invalidating cache at '%s'" % self.__archive_path)
self.opts.log.warning(' thumb_width changed: %1.2f" => %1.2f"' %
(float(cached_thumb_width),float(self.opts.thumb_width)))
- os.remove(self.__archive_path)
with ZipFile(self.__archive_path, mode='w') as zfw:
zfw.writestr("Catalog Thumbs Archive",'')
else:
diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py
index cbda615677..611aa1cc89 100644
--- a/src/calibre/library/database2.py
+++ b/src/calibre/library/database2.py
@@ -102,7 +102,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
if self.user_version == 0:
self.initialize_database()
# remember to add any filter to the connect method in sqlite.py as well
- # so that various code taht connects directly will not complain about
+ # so that various code that connects directly will not complain about
# missing functions
self.books_list_filter = self.conn.create_dynamic_filter('books_list_filter')
# Store temporary tables in memory
@@ -113,7 +113,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
def exists_at(cls, path):
return path and os.path.exists(os.path.join(path, 'metadata.db'))
- def __init__(self, library_path, row_factory=False, default_prefs=None):
+ def __init__(self, library_path, row_factory=False, default_prefs=None,
+ read_only=False):
self.field_metadata = FieldMetadata()
self.dirtied_queue = Queue()
if not os.path.exists(library_path):
@@ -127,6 +128,14 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
if isinstance(self.dbpath, unicode) and not iswindows:
self.dbpath = self.dbpath.encode(filesystem_encoding)
+ if read_only and os.path.exists(self.dbpath):
+ # Work on only a copy of metadata.db to ensure that
+ # metadata.db is not changed
+ pt = PersistentTemporaryFile('_metadata_ro.db')
+ pt.close()
+ shutil.copyfile(self.dbpath, pt.name)
+ self.dbpath = pt.name
+
apply_default_prefs = not os.path.exists(self.dbpath)
self.connect()
@@ -2769,7 +2778,6 @@ books_series_link feeds
os.remove(dest)
raise
else:
- os.remove(self.dbpath)
shutil.copyfile(dest, self.dbpath)
self.connect()
self.initialize_dynamic()