Merge from trunk

This commit is contained in:
Sengian 2010-12-16 00:30:25 +01:00
commit 569cfefe16
14 changed files with 126 additions and 11 deletions

View File

@ -80,6 +80,34 @@ class Plugin(object): # {{{
'''
pass
def load_resources(self, names):
'''
If this plugin comes in a ZIP file (user added plugin), this method
will allow you to load resources from the ZIP file.
For example to load an image::
pixmap = QPixmap()
pixmap.loadFromData(self.load_resources(['images/icon.png']).itervalues().next())
icon = QIcon(pixmap)
:param names: List of paths to resources in the zip file using / as separator
:return: A dictionary of the form ``{name : file_contents}``. Any names
that were not found in the zip file will not be present in the
dictionary.
'''
if self.plugin_path is None:
raise ValueError('This plugin was not loaded from a ZIP file')
ans = {}
with zipfile.ZipFile(self.plugin_path, 'r') as zf:
for candidate in zf.namelist():
if candidate in names:
ans[candidate] = zf.read(candidate)
return ans
def customization_help(self, gui=False):
'''
Return a string giving help on how to customize this plugin.

View File

@ -540,6 +540,7 @@ def choose_dir(window, name, title, default_dir='~'):
parent=window, name=name, mode=QFileDialog.Directory,
default_dir=default_dir)
dir = fd.get_files()
fd.setParent(None)
if dir:
return dir[0]
@ -560,6 +561,7 @@ def choose_files(window, name, title,
fd = FileDialog(title=title, name=name, filters=filters,
parent=window, add_all_files_filter=all_files, mode=mode,
)
fd.setParent(None)
if fd.accepted:
return fd.get_files()
return None
@ -570,6 +572,7 @@ def choose_images(window, name, title, select_only_single_file=True):
filters=[('Images', ['png', 'gif', 'jpeg', 'jpg', 'svg'])],
parent=window, add_all_files_filter=False, mode=mode,
)
fd.setParent(None)
if fd.accepted:
return fd.get_files()
return None

View File

@ -6,6 +6,7 @@ __copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
from functools import partial
from zipfile import ZipFile
from PyQt4.Qt import QToolButton, QAction, QIcon, QObject
@ -108,6 +109,34 @@ class InterfaceAction(QObject):
setattr(self, attr, action)
return action
def load_resources(self, names):
'''
If this plugin comes in a ZIP file (user added plugin), this method
will allow you to load resources from the ZIP file.
For example to load an image::
pixmap = QPixmap()
pixmap.loadFromData(self.load_resources(['images/icon.png']).itervalues().next())
icon = QIcon(pixmap)
:param names: List of paths to resources in the zip file using / as separator
:return: A dictionary of the form ``{name : file_contents}``. Any names
that were not found in the zip file will not be present in the
dictionary.
'''
if self.plugin_path is None:
raise ValueError('This plugin was not loaded from a ZIP file')
ans = {}
with ZipFile(self.plugin_path, 'r') as zf:
for candidate in zf.namelist():
if candidate in names:
ans[candidate] = zf.read(candidate)
return ans
def genesis(self):
'''
Setup this plugin. Only called once during initialization. self.gui is

View File

@ -243,7 +243,9 @@ class AddAction(InterfaceAction):
if hasattr(self._adder, 'cleanup'):
self._adder.cleanup()
self._adder = None
self._adder.setParent(None)
del self._adder
self._adder = None
def _add_from_device_adder(self, paths=[], names=[], infos=[],
on_card=None, model=None):

View File

@ -160,15 +160,17 @@ class ChooseLibraryAction(InterfaceAction):
self.action_choose.triggered.connect(self.choose_library,
type=Qt.QueuedConnection)
self.choose_menu = QMenu(self.gui)
self.choose_menu.addAction(self.action_choose)
self.qaction.setMenu(self.choose_menu)
self.quick_menu = QMenu(_('Quick switch'))
self.quick_menu_action = self.choose_menu.addMenu(self.quick_menu)
self.rename_menu = QMenu(_('Rename library'))
self.rename_menu_action = self.choose_menu.addMenu(self.rename_menu)
self.delete_menu = QMenu(_('Delete library'))
self.delete_menu_action = self.choose_menu.addMenu(self.delete_menu)
if not os.environ.get('CALIBRE_OVERRIDE_DATABASE_PATH', None):
self.choose_menu.addAction(self.action_choose)
self.quick_menu = QMenu(_('Quick switch'))
self.quick_menu_action = self.choose_menu.addMenu(self.quick_menu)
self.rename_menu = QMenu(_('Rename library'))
self.rename_menu_action = self.choose_menu.addMenu(self.rename_menu)
self.delete_menu = QMenu(_('Delete library'))
self.delete_menu_action = self.choose_menu.addMenu(self.delete_menu)
self.rename_separator = self.choose_menu.addSeparator()
@ -223,6 +225,8 @@ class ChooseLibraryAction(InterfaceAction):
self.library_changed(self.gui.library_view.model().db)
def build_menus(self):
if os.environ.get('CALIBRE_OVERRIDE_DATABASE_PATH', None):
return
db = self.gui.library_view.model().db
locations = list(self.stats.locations(db))
for ac in self.switch_actions:
@ -387,6 +391,11 @@ class ChooseLibraryAction(InterfaceAction):
c.exec_()
def change_library_allowed(self):
if os.environ.get('CALIBRE_OVERRIDE_DATABASE_PATH', None):
warning_dialog(self.gui, _('Not allowed'),
_('You cannot change libraries while using the environment'
' variable CALIBRE_OVERRIDE_DATABASE_PATH.'), show=True)
return False
if self.gui.job_manager.has_jobs():
warning_dialog(self.gui, _('Not allowed'),
_('You cannot change libraries while jobs'

View File

@ -12,7 +12,7 @@ from threading import Thread
from PyQt4.Qt import QMenu, QToolButton
from calibre.gui2.actions import InterfaceAction
from calibre.gui2 import error_dialog, Dispatcher
from calibre.gui2 import error_dialog, Dispatcher, warning_dialog
from calibre.gui2.dialogs.progress import ProgressDialog
from calibre.utils.config import prefs, tweaks
@ -106,6 +106,9 @@ class CopyToLibraryAction(InterfaceAction):
def build_menus(self):
self.menu.clear()
if os.environ.get('CALIBRE_OVERRIDE_DATABASE_PATH', None):
self.menu.addAction('disabled', self.cannot_do_dialog)
return
db = self.gui.library_view.model().db
locations = list(self.stats.locations(db))
for name, loc in locations:
@ -160,5 +163,9 @@ class CopyToLibraryAction(InterfaceAction):
self.gui.iactions['Remove Books'].library_ids_deleted(
self.worker.processed, row)
def cannot_do_dialog(self):
warning_dialog(self.gui, _('Not allowed'),
_('You cannot use other libraries while using the environment'
' variable CALIBRE_OVERRIDE_DATABASE_PATH.'), show=True)

View File

@ -368,6 +368,15 @@ class Adder(QObject): # {{{
shutil.rmtree(self.worker.tdir)
except:
pass
self._parent = None
self.pd.setParent(None)
del self.pd
self.pd = None
if hasattr(self, 'db_adder'):
self.db_adder.setParent(None)
del self.db_adder
self.db_adder = None
@property
def number_of_books_added(self):

View File

@ -166,7 +166,9 @@ class DeviceManager(Thread): # {{{
report_progress=self.report_progress)
dev.open()
except OpenFeedback, e:
self.open_feedback_msg(dev.get_gui_name(), e.feedback_msg)
if dev not in self.ejected_devices:
self.open_feedback_msg(dev.get_gui_name(), e.feedback_msg)
self.ejected_devices.add(dev)
continue
except:
tb = traceback.format_exc()

View File

@ -103,6 +103,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
acmap = OrderedDict()
for action in interface_actions():
ac = action.load_actual_plugin(self)
ac.plugin_path = action.plugin_path
if ac.name in acmap:
if ac.priority >= acmap[ac.name].priority:
acmap[ac.name] = ac

View File

@ -171,6 +171,13 @@
</property>
</widget>
</item>
<item row="8" column="0" colspan="2">
<widget class="QCheckBox" name="opt_remember_current_page">
<property name="text">
<string>Remember the &amp;current page when quitting</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="max_view_width">
<property name="suffix">

View File

@ -50,6 +50,8 @@ def config(defaults=None):
c.add_opt('hyphenate', default=False, help=_('Hyphenate text'))
c.add_opt('hyphenate_default_lang', default='en',
help=_('Default language for hyphenation rules'))
c.add_opt('remember_current_page', default=True,
help=_('Save the current position in the document, when quitting'))
fonts = c.add_group('FONTS', _('Font options'))
fonts('serif_family', default='Times New Roman' if iswindows else 'Liberation Serif',
@ -72,6 +74,7 @@ class ConfigDialog(QDialog, Ui_Dialog):
opts = config().parse()
self.opt_remember_window_size.setChecked(opts.remember_window_size)
self.opt_remember_current_page.setChecked(opts.remember_current_page)
self.serif_family.setCurrentFont(QFont(opts.serif_family))
self.sans_family.setCurrentFont(QFont(opts.sans_family))
self.mono_family.setCurrentFont(QFont(opts.mono_family))
@ -118,6 +121,7 @@ class ConfigDialog(QDialog, Ui_Dialog):
c.set('fit_images', self.opt_fit_images.isChecked())
c.set('max_view_width', int(self.max_view_width.value()))
c.set('hyphenate', self.hyphenate.isChecked())
c.set('remember_current_page', self.opt_remember_current_page.isChecked())
idx = self.hyphenate_default_lang.currentIndex()
c.set('hyphenate_default_lang',
str(self.hyphenate_default_lang.itemData(idx).toString()))

View File

@ -328,6 +328,11 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
c = config().parse()
self.frame.setMaximumWidth(c.max_view_width)
def get_remember_current_page_opt(self):
from calibre.gui2.viewer.documentview import config
c = config().parse()
return c.remember_current_page
def print_book(self, preview):
Printing(self.iterator.spine, preview)
@ -578,7 +583,8 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
current_page = None
self.existing_bookmarks = []
for bm in bookmarks:
if bm[0] == 'calibre_current_page_bookmark':
if bm[0] == 'calibre_current_page_bookmark' and \
self.get_remember_current_page_opt():
current_page = bm
else:
self.existing_bookmarks.append(bm[0])
@ -598,6 +604,8 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
self.set_bookmarks(bookmarks)
def save_current_position(self):
if not self.get_remember_current_page_opt():
return
try:
pos = self.view.bookmark()
bookmark = '%d#%s'%(self.current_index, pos)

View File

@ -425,3 +425,7 @@ class SchemaUpgrade(object):
ids = [(x[0],) for x in data if has_cover(x[1])]
self.conn.executemany('UPDATE books SET has_cover=1 WHERE id=?', ids)
def upgrade_version_15(self):
'Remove commas from tags'
self.conn.execute("UPDATE tags SET name=REPLACE(name, ',', ';')")

View File

@ -72,3 +72,5 @@ Precautions
--------------
Portable media can occasionally fail so you should make periodic backups of you Calibre library. This can be done by making a copy of the CalibreLibrary folder and all its contents. There are many freely available tools around that can optimise such back processes, well known ones being RoboCopy and RichCopy. However you can simply use a Windows copy facility if you cannot be bothered to use a specialised tools.
Using the environment variable CALIBRE_OVERRIDE_DATABASE_PATH disables multiple-library support in |app|. Avoid setting this variable in calibre-portable.bat unless you really need it.