%PDF- %PDF-
| Direktori : /lib/calibre/calibre/gui2/dialogs/ |
| Current File : //lib/calibre/calibre/gui2/dialogs/catalog.py |
#!/usr/bin/env python3
__license__ = 'GPL v3'
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
import importlib
import os
import sys
import weakref
from qt.core import (
QApplication, QDialog, QDialogButtonBox, QScrollArea, QSize
)
from calibre.customize import PluginInstallationType
from calibre.customize.ui import catalog_plugins, config
from calibre.gui2 import dynamic, info_dialog
from calibre.gui2.dialogs.catalog_ui import Ui_Dialog
class Catalog(QDialog, Ui_Dialog):
''' Catalog Dialog builder'''
def __init__(self, parent, dbspec, ids, db):
import re
from PyQt5.uic import compileUi
from calibre import prints as info
QDialog.__init__(self, parent)
self.setupUi(self)
self.dbspec, self.ids = dbspec, ids
# Display the number of books we've been passed
self.count.setText(str(self.count.text()).format(len(ids)))
# Display the last-used title
self.title.setText(dynamic.get('catalog_last_used_title',
_('My books')))
self.fmts, self.widgets = [], []
for plugin in catalog_plugins():
if plugin.name in config['disabled_plugins']:
continue
name = plugin.name.lower().replace(' ', '_')
if getattr(plugin, 'installation_type', None) is PluginInstallationType.BUILTIN:
try:
catalog_widget = importlib.import_module('calibre.gui2.catalog.'+name)
pw = catalog_widget.PluginWidget()
pw.parent_ref = weakref.ref(self)
pw.initialize(name, db)
pw.ICON = I('forward.png')
self.widgets.append(pw)
[self.fmts.append([file_type.upper(), pw.sync_enabled,pw]) for file_type in plugin.file_types]
except ImportError:
info("ImportError initializing %s" % name)
continue
else:
# Load dynamic tab
form = os.path.join(plugin.resources_path,'%s.ui' % name)
klass = os.path.join(plugin.resources_path,'%s.py' % name)
compiled_form = os.path.join(plugin.resources_path,'%s_ui.py' % name)
if os.path.exists(form) and os.path.exists(klass):
# info("Adding widget for user-installed Catalog plugin %s" % plugin.name)
# Compile the .ui form provided in plugin.zip
if not os.path.exists(compiled_form):
from polyglot.io import PolyglotStringIO
# info('\tCompiling form', form)
buf = PolyglotStringIO()
compileUi(form, buf)
dat = buf.getvalue()
dat = re.compile(r'QtGui.QApplication.translate\(.+?,\s+"(.+?)(?<!\\)",.+?\)',
re.DOTALL).sub(r'_("\1")', dat)
open(compiled_form, 'wb').write(dat.encode('utf-8'))
# Import the dynamic PluginWidget() from .py file provided in plugin.zip
try:
sys.path.insert(0, plugin.resources_path)
catalog_widget = importlib.import_module(name)
pw = catalog_widget.PluginWidget()
pw.initialize(name)
pw.ICON = I('forward.png')
self.widgets.append(pw)
[self.fmts.append([file_type.upper(), pw.sync_enabled,pw]) for file_type in plugin.file_types]
except ImportError:
info("ImportError with %s" % name)
continue
finally:
sys.path.remove(plugin.resources_path)
else:
info("No dynamic tab resources found for %s" % name)
self.widgets = sorted(self.widgets, key=lambda x: x.TITLE)
# Generate a sorted list of installed catalog formats/sync_enabled pairs
fmts = sorted(x[0] for x in self.fmts)
self.sync_enabled_formats = []
for fmt in self.fmts:
if fmt[1]:
self.sync_enabled_formats.append(fmt[0])
# Callbacks when format, title changes
self.format.currentIndexChanged.connect(self.format_changed)
self.format.currentIndexChanged.connect(self.settings_changed)
self.title.editingFinished.connect(self.settings_changed)
# Add the installed catalog format list to the format QComboBox
self.format.blockSignals(True)
self.format.addItems(fmts)
pref = dynamic.get('catalog_preferred_format', 'CSV')
idx = self.format.findText(pref)
if idx > -1:
self.format.setCurrentIndex(idx)
self.format.blockSignals(False)
if self.sync.isEnabled():
self.sync.setChecked(dynamic.get('catalog_sync_to_device', True))
self.add_to_library.setChecked(dynamic.get('catalog_add_to_library', True))
self.format.currentIndexChanged.connect(self.show_plugin_tab)
self.buttonBox.button(QDialogButtonBox.StandardButton.Apply).clicked.connect(self.apply)
self.buttonBox.button(QDialogButtonBox.StandardButton.Help).clicked.connect(self.help)
self.show_plugin_tab(None)
geom = dynamic.get('catalog_window_geom', None)
if geom is not None:
QApplication.instance().safe_restore_geometry(self, bytes(geom))
else:
self.resize(self.sizeHint())
g = self.screen().availableSize()
self.setMaximumWidth(g.width() - 50)
self.setMaximumHeight(g.height() - 50)
def sizeHint(self):
geom = self.screen().availableSize()
nh, nw = max(300, geom.height()-50), max(400, geom.width()-70)
return QSize(nw, nh)
@property
def options_widget(self):
ans = self.tabs.widget(1)
if isinstance(ans, QScrollArea):
ans = ans.widget()
return ans
def show_plugin_tab(self, idx):
cf = str(self.format.currentText()).lower()
while self.tabs.count() > 1:
self.tabs.removeTab(1)
for pw in self.widgets:
if cf in pw.formats:
if getattr(pw, 'handles_scrolling', False):
self.tabs.addTab(pw, pw.TITLE)
else:
self.sw__mem = s = QScrollArea(self)
s.setWidget(pw), s.setWidgetResizable(True)
self.tabs.addTab(s, pw.TITLE)
break
if hasattr(self.options_widget, 'show_help'):
self.buttonBox.button(QDialogButtonBox.StandardButton.Help).setVisible(True)
else:
self.buttonBox.button(QDialogButtonBox.StandardButton.Help).setVisible(False)
def format_changed(self, idx):
cf = str(self.format.currentText())
if cf in self.sync_enabled_formats:
self.sync.setEnabled(True)
else:
self.sync.setDisabled(True)
self.sync.setChecked(False)
def settings_changed(self):
'''
When title/format change, invalidate Preset in E-book options tab
'''
cf = str(self.format.currentText()).lower()
if cf in ('azw3', 'epub', 'mobi') and hasattr(self.options_widget, 'settings_changed'):
self.options_widget.settings_changed("title/format")
@property
def fmt_options(self):
ans = {}
if self.tabs.count() > 1:
w = self.options_widget
ans = w.options()
return ans
def save_catalog_settings(self):
self.catalog_format = str(self.format.currentText())
dynamic.set('catalog_preferred_format', self.catalog_format)
self.catalog_title = str(self.title.text())
dynamic.set('catalog_last_used_title', self.catalog_title)
self.catalog_sync = bool(self.sync.isChecked())
dynamic.set('catalog_sync_to_device', self.catalog_sync)
dynamic.set('catalog_window_geom', bytearray(self.saveGeometry()))
dynamic.set('catalog_add_to_library', self.add_to_library.isChecked())
def apply(self, *args):
# Store current values without building catalog
self.save_catalog_settings()
if self.tabs.count() > 1:
self.options_widget.options()
def accept(self):
self.save_catalog_settings()
return QDialog.accept(self)
def help(self):
'''
To add help functionality for a specific format:
In gui2.catalog.catalog_<format>.py, add the following:
from calibre.gui2 import open_url
from qt.core import QUrl
In the PluginWidget() class, add this method:
def show_help(self):
url = 'file:///' + P('catalog/help_<format>.html')
open_url(QUrl(url))
Create the help file at resources/catalog/help_<format>.html
'''
if self.tabs.count() > 1 and hasattr(self.options_widget,'show_help'):
try:
self.options_widget.show_help()
except:
info_dialog(self, _('No help available'),
_('No help available for this output format.'),
show_copy_button=False,
show=True)
def reject(self):
dynamic.set('catalog_window_geom', bytearray(self.saveGeometry()))
QDialog.reject(self)