mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
String changes
This commit is contained in:
parent
56b81a89dc
commit
002f941c7d
@ -79,9 +79,9 @@ The four sub-directories are:
|
|||||||
========== =============
|
========== =============
|
||||||
|
|
||||||
If you want to edit the input document a little before having calibre convert it, the best thing to
|
If you want to edit the input document a little before having calibre convert it, the best thing to
|
||||||
do is edit the files in the :file:`input` sub-directory, then zip it up, and use the zip file as the
|
do is edit the files in the :file:`input` sub-directory, then ZIP it up, and use the ZIP file as the
|
||||||
input format for subsequent conversions. To do this use the :guilabel:`Edit meta information` dialog
|
input format for subsequent conversions. To do this use the :guilabel:`Edit meta information` dialog
|
||||||
to add the zip file as a format for the book and then, in the top left corner of the conversion dialog,
|
to add the ZIP file as a format for the book and then, in the top left corner of the conversion dialog,
|
||||||
select ZIP as the input format.
|
select ZIP as the input format.
|
||||||
|
|
||||||
This document will deal mainly with the various transforms that operate on the intermediate XHTML
|
This document will deal mainly with the various transforms that operate on the intermediate XHTML
|
||||||
@ -735,7 +735,7 @@ output ranging anywhere from decent to unusable, depending on the input PDF.
|
|||||||
Comic book collections
|
Comic book collections
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
A comic book collection is a .cbc file. A .cbc file is a zip file that contains other CBZ/CBR files. In addition the
|
A comic book collection is a .cbc file. A .cbc file is a ZIP file that contains other CBZ/CBR files. In addition the
|
||||||
.cbc file must contain a simple text file called comics.txt, encoded in UTF-8. The comics.txt file must contain
|
.cbc file must contain a simple text file called comics.txt, encoded in UTF-8. The comics.txt file must contain
|
||||||
a list of the comics files inside the .cbc file, in the form filename:title, as shown below::
|
a list of the comics files inside the .cbc file, in the form filename:title, as shown below::
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ Here, we will teach you how to create your own plugins to add new features to ca
|
|||||||
Anatomy of a calibre plugin
|
Anatomy of a calibre plugin
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
A calibre plugin is very simple, it's just a zip file that contains some Python code
|
A calibre plugin is very simple, it's just a ZIP file that contains some Python code
|
||||||
and any other resources like image files needed by the plugin. Without further ado,
|
and any other resources like image files needed by the plugin. Without further ado,
|
||||||
let's see a basic example.
|
let's see a basic example.
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ A User Interface plugin
|
|||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
This plugin will be spread over a few files (to keep the code clean). It will show you how to get resources
|
This plugin will be spread over a few files (to keep the code clean). It will show you how to get resources
|
||||||
(images or data files) from the plugin zip file, allow users to configure your plugin,
|
(images or data files) from the plugin ZIP file, allow users to configure your plugin,
|
||||||
how to create elements in the calibre user interface and how to access
|
how to create elements in the calibre user interface and how to access
|
||||||
and query the books database in calibre.
|
and query the books database in calibre.
|
||||||
|
|
||||||
@ -58,19 +58,19 @@ You can download this plugin from `interface_demo_plugin.zip <https://calibre-eb
|
|||||||
|
|
||||||
.. _import_name_txt:
|
.. _import_name_txt:
|
||||||
|
|
||||||
The first thing to note is that this zip file has a lot more files in it, explained below, pay particular attention to
|
The first thing to note is that this ZIP file has a lot more files in it, explained below, pay particular attention to
|
||||||
``plugin-import-name-interface_demo.txt``.
|
``plugin-import-name-interface_demo.txt``.
|
||||||
|
|
||||||
**plugin-import-name-interface_demo.txt**
|
**plugin-import-name-interface_demo.txt**
|
||||||
An empty text file used to enable the multi-file plugin magic. This file must be present in all plugins that use
|
An empty text file used to enable the multi-file plugin magic. This file must be present in all plugins that use
|
||||||
more than one .py file. It should be empty and its filename must be of the form: plugin-import-name-**some_name**.txt
|
more than one .py file. It should be empty and its filename must be of the form: plugin-import-name-**some_name**.txt
|
||||||
The presence of this file allows you to import code from the .py files present inside the zip file, using a statement like::
|
The presence of this file allows you to import code from the .py files present inside the ZIP file, using a statement like::
|
||||||
|
|
||||||
from calibre_plugins.some_name.some_module import some_object
|
from calibre_plugins.some_name.some_module import some_object
|
||||||
|
|
||||||
The prefix ``calibre_plugins`` must always be present. ``some_name`` comes from the filename of the empty text file.
|
The prefix ``calibre_plugins`` must always be present. ``some_name`` comes from the filename of the empty text file.
|
||||||
``some_module`` refers to :file:`some_module.py` file inside the zip file. Note that this importing is just as
|
``some_module`` refers to :file:`some_module.py` file inside the ZIP file. Note that this importing is just as
|
||||||
powerful as regular Python imports. You can create packages and subpackages of .py modules inside the zip file,
|
powerful as regular Python imports. You can create packages and subpackages of .py modules inside the ZIP file,
|
||||||
just like you would normally (by defining __init__.py in each sub-directory), and everything should Just Work.
|
just like you would normally (by defining __init__.py in each sub-directory), and everything should Just Work.
|
||||||
|
|
||||||
The name you use for ``some_name`` enters a global namespace shared by all plugins, **so make it as unique as possible**.
|
The name you use for ``some_name`` enters a global namespace shared by all plugins, **so make it as unique as possible**.
|
||||||
@ -108,10 +108,10 @@ First, the obligatory ``__init__.py`` to define the plugin metadata:
|
|||||||
|
|
||||||
The only noteworthy feature is the field :attr:`actual_plugin`. Since calibre has both command line and GUI interfaces,
|
The only noteworthy feature is the field :attr:`actual_plugin`. Since calibre has both command line and GUI interfaces,
|
||||||
GUI plugins like this one should not load any GUI libraries in __init__.py. The actual_plugin field does this for you,
|
GUI plugins like this one should not load any GUI libraries in __init__.py. The actual_plugin field does this for you,
|
||||||
by telling calibre that the actual plugin is to be found in another file inside your zip archive, which will only be loaded
|
by telling calibre that the actual plugin is to be found in another file inside your ZIP archive, which will only be loaded
|
||||||
in a GUI context.
|
in a GUI context.
|
||||||
|
|
||||||
Remember that for this to work, you must have a plugin-import-name-some_name.txt file in your plugin zip file,
|
Remember that for this to work, you must have a plugin-import-name-some_name.txt file in your plugin ZIP file,
|
||||||
as discussed above.
|
as discussed above.
|
||||||
|
|
||||||
Also there are a couple of methods for enabling user configuration of the plugin. These are discussed below.
|
Also there are a couple of methods for enabling user configuration of the plugin. These are discussed below.
|
||||||
@ -132,21 +132,21 @@ The actual logic to implement the Interface Plugin Demo dialog.
|
|||||||
.. literalinclude:: plugin_examples/interface_demo/main.py
|
.. literalinclude:: plugin_examples/interface_demo/main.py
|
||||||
:lines: 16-
|
:lines: 16-
|
||||||
|
|
||||||
Getting resources from the plugin zip file
|
Getting resources from the plugin ZIP file
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
calibre's plugin loading system defines a couple of built-in functions that allow you to conveniently get files from the plugin zip file.
|
calibre's plugin loading system defines a couple of built-in functions that allow you to conveniently get files from the plugin ZIP file.
|
||||||
|
|
||||||
**get_resources(name_or_list_of_names)**
|
**get_resources(name_or_list_of_names)**
|
||||||
This function should be called with a list of paths to files inside the zip file. For example to access the file icon.png in
|
This function should be called with a list of paths to files inside the ZIP file. For example to access the file icon.png in
|
||||||
the directory images in the zip file, you would use: ``images/icon.png``. Always use a forward slash as the path separator,
|
the directory images in the ZIP file, you would use: ``images/icon.png``. Always use a forward slash as the path separator,
|
||||||
even on windows. When you pass in a single name, the function will return the raw bytes of that file or None if the name
|
even on windows. When you pass in a single name, the function will return the raw bytes of that file or None if the name
|
||||||
was not found in the zip file. If you pass in more than one name then it returns a dict mapping the names to bytes.
|
was not found in the ZIP file. If you pass in more than one name then it returns a dict mapping the names to bytes.
|
||||||
If a name is not found, it will not be present in the returned dict.
|
If a name is not found, it will not be present in the returned dict.
|
||||||
|
|
||||||
**get_icons(name_or_list_of_names)**
|
**get_icons(name_or_list_of_names)**
|
||||||
A convenience wrapper for get_resources() that creates QIcon objects from the raw bytes returned by get_resources.
|
A convenience wrapper for get_resources() that creates QIcon objects from the raw bytes returned by get_resources.
|
||||||
If a name is not found in the zip file the corresponding QIcon will be null.
|
If a name is not found in the ZIP file the corresponding QIcon will be null.
|
||||||
|
|
||||||
Enabling user configuration of your plugin
|
Enabling user configuration of your plugin
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -94,7 +94,7 @@ up your icons into a theme. To do so, go to
|
|||||||
:guilabel:`Preferences->Miscellaneous->Create icon theme`, select the folder
|
:guilabel:`Preferences->Miscellaneous->Create icon theme`, select the folder
|
||||||
where you have put your icons (usually the :file:`resources/images` folder in
|
where you have put your icons (usually the :file:`resources/images` folder in
|
||||||
the calibre config directory, as described above). Then fill up the theme
|
the calibre config directory, as described above). Then fill up the theme
|
||||||
metadata and click OK. This will result in a zip file containing the theme
|
metadata and click OK. This will result in a ZIP file containing the theme
|
||||||
icons. You can upload that to the calibre forum at `Mobileread
|
icons. You can upload that to the calibre forum at `Mobileread
|
||||||
<https://www.mobileread.com/forums/forumdisplay.php?f=166>`_ and then I will
|
<https://www.mobileread.com/forums/forumdisplay.php?f=166>`_ and then I will
|
||||||
make your theme available via calibre's builtin icon theme system.
|
make your theme available via calibre's builtin icon theme system.
|
||||||
|
@ -26,7 +26,7 @@ For example, adding support for a new device to calibre typically involves writi
|
|||||||
a device driver plugin. You can browse the
|
a device driver plugin. You can browse the
|
||||||
`built-in drivers <https://github.com/kovidgoyal/calibre/tree/master/src/calibre/devices>`_. Similarly, adding support
|
`built-in drivers <https://github.com/kovidgoyal/calibre/tree/master/src/calibre/devices>`_. Similarly, adding support
|
||||||
for new conversion formats involves writing input/output format plugins. Another example of the modular design is the :ref:`recipe system <news>` for
|
for new conversion formats involves writing input/output format plugins. Another example of the modular design is the :ref:`recipe system <news>` for
|
||||||
fetching news. For more examples of plugins designed to add features to calibre, see the `plugin index <https://www.mobileread.com/forums/showthread.php?p=1362767#post1362767>`_.
|
fetching news. For more examples of plugins designed to add features to calibre, see the `Index of plugins <https://www.mobileread.com/forums/showthread.php?p=1362767#post1362767>`_.
|
||||||
|
|
||||||
.. _code_layout:
|
.. _code_layout:
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ How do I convert my file containing non-English characters, or smart quotes?
|
|||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
There are two aspects to this problem:
|
There are two aspects to this problem:
|
||||||
1. Knowing the encoding of the source file: calibre tries to guess what character encoding your source files use, but often, this is impossible, so you need to tell it what encoding to use. This can be done in the GUI via the :guilabel:`Input character encoding` field in the :guilabel:`Look & feel->Text` section of the conversion dialog. The command-line tools have an :option:`ebook-convert-txt-input --input-encoding` option.
|
1. Knowing the encoding of the source file: calibre tries to guess what character encoding your source files use, but often, this is impossible, so you need to tell it what encoding to use. This can be done in the GUI via the :guilabel:`Input character encoding` field in the :guilabel:`Look & feel->Text` section of the conversion dialog. The command-line tools have an :option:`ebook-convert-txt-input --input-encoding` option.
|
||||||
2. When adding HTML files to calibre, you may need to tell calibre what encoding the files are in. To do this go to :guilabel:`Preferences->Plugins->File Type plugins` and customize the HTML2Zip plugin, telling it what encoding your HTML files are in. Now when you add HTML files to calibre they will be correctly processed. HTML files from different sources often have different encodings, so you may have to change this setting repeatedly. A common encoding for many files from the web is ``cp1252`` and I would suggest you try that first. Note that when converting HTML files, leave the input encoding setting mentioned above blank. This is because the HTML2ZIP plugin automatically converts the HTML files to a standard encoding (utf-8).
|
2. When adding HTML files to calibre, you may need to tell calibre what encoding the files are in. To do this go to :guilabel:`Preferences->Advanced->Plugins->File Type plugins` and customize the HTML2Zip plugin, telling it what encoding your HTML files are in. Now when you add HTML files to calibre they will be correctly processed. HTML files from different sources often have different encodings, so you may have to change this setting repeatedly. A common encoding for many files from the web is ``cp1252`` and I would suggest you try that first. Note that when converting HTML files, leave the input encoding setting mentioned above blank. This is because the HTML2ZIP plugin automatically converts the HTML files to a standard encoding (utf-8).
|
||||||
|
|
||||||
What's the deal with Table of Contents in MOBI files?
|
What's the deal with Table of Contents in MOBI files?
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -154,7 +154,7 @@ The base class for such devices is :class:`calibre.devices.usbms.driver.USBMS`.
|
|||||||
User Interface Actions
|
User Interface Actions
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
If you are adding your own plugin in a zip file, you should subclass both InterfaceActionBase and InterfaceAction. The :meth:`load_actual_plugin` method of your InterfaceActionBase subclass must return an instantiated object of your InterfaceBase subclass.
|
If you are adding your own plugin in a ZIP file, you should subclass both InterfaceActionBase and InterfaceAction. The :meth:`load_actual_plugin` method of your InterfaceActionBase subclass must return an instantiated object of your InterfaceBase subclass.
|
||||||
|
|
||||||
|
|
||||||
.. autoclass:: calibre.gui2.actions.InterfaceAction
|
.. autoclass:: calibre.gui2.actions.InterfaceAction
|
||||||
|
@ -17,7 +17,7 @@ You obtain a container object for a book at a path like this::
|
|||||||
from calibre.ebooks.oeb.polish.container import get_container
|
from calibre.ebooks.oeb.polish.container import get_container
|
||||||
container = get_container('Path to book file', tweak_mode=True)
|
container = get_container('Path to book file', tweak_mode=True)
|
||||||
|
|
||||||
If you are writing a plugin for the e-book editor, you get the current container
|
If you are writing a plugin for the E-book editor, you get the current container
|
||||||
for the book being edited like this::
|
for the book being edited like this::
|
||||||
|
|
||||||
from calibre.gui2.tweak_book import current_container
|
from calibre.gui2.tweak_book import current_container
|
||||||
|
@ -26,7 +26,7 @@ class Plugin(object): # {{{
|
|||||||
'''
|
'''
|
||||||
A calibre plugin. Useful members include:
|
A calibre plugin. Useful members include:
|
||||||
|
|
||||||
* ``self.plugin_path``: Stores path to the zip file that contains
|
* ``self.plugin_path``: Stores path to the ZIP file that contains
|
||||||
this plugin or None if it is a builtin
|
this plugin or None if it is a builtin
|
||||||
plugin
|
plugin
|
||||||
* ``self.site_customization``: Stores a customization string entered
|
* ``self.site_customization``: Stores a customization string entered
|
||||||
@ -91,7 +91,7 @@ class Plugin(object): # {{{
|
|||||||
plugin will be initialized for every new worker process.
|
plugin will be initialized for every new worker process.
|
||||||
|
|
||||||
Perform any plugin specific initialization here, such as extracting
|
Perform any plugin specific initialization here, such as extracting
|
||||||
resources from the plugin zip file. The path to the zip file is
|
resources from the plugin ZIP file. The path to the ZIP file is
|
||||||
available as ``self.plugin_path``.
|
available as ``self.plugin_path``.
|
||||||
|
|
||||||
Note that ``self.site_customization`` is **not** available at this point.
|
Note that ``self.site_customization`` is **not** available at this point.
|
||||||
@ -213,10 +213,10 @@ class Plugin(object): # {{{
|
|||||||
pixmap.loadFromData(self.load_resources(['images/icon.png']).itervalues().next())
|
pixmap.loadFromData(self.load_resources(['images/icon.png']).itervalues().next())
|
||||||
icon = QIcon(pixmap)
|
icon = QIcon(pixmap)
|
||||||
|
|
||||||
:param names: List of paths to resources in the zip file using / as separator
|
: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
|
: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
|
that were not found in the ZIP file will not be present in the
|
||||||
dictionary.
|
dictionary.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
@ -402,7 +402,7 @@ class MetadataReaderPlugin(Plugin): # {{{
|
|||||||
'''
|
'''
|
||||||
A plugin that implements reading metadata from a set of file types.
|
A plugin that implements reading metadata from a set of file types.
|
||||||
'''
|
'''
|
||||||
#: Set of file types for which this plugin should be run
|
#: Set of file types for which this plugin should be run.
|
||||||
#: For example: ``set(['lit', 'mobi', 'prc'])``
|
#: For example: ``set(['lit', 'mobi', 'prc'])``
|
||||||
file_types = set([])
|
file_types = set([])
|
||||||
|
|
||||||
@ -434,7 +434,7 @@ class MetadataWriterPlugin(Plugin): # {{{
|
|||||||
'''
|
'''
|
||||||
A plugin that implements reading metadata from a set of file types.
|
A plugin that implements reading metadata from a set of file types.
|
||||||
'''
|
'''
|
||||||
#: Set of file types for which this plugin should be run
|
#: Set of file types for which this plugin should be run.
|
||||||
#: For example: ``set(['lit', 'mobi', 'prc'])``
|
#: For example: ``set(['lit', 'mobi', 'prc'])``
|
||||||
file_types = set([])
|
file_types = set([])
|
||||||
|
|
||||||
@ -470,7 +470,7 @@ class CatalogPlugin(Plugin): # {{{
|
|||||||
|
|
||||||
resources_path = None
|
resources_path = None
|
||||||
|
|
||||||
#: Output file type for which this plugin should be run
|
#: Output file type for which this plugin should be run.
|
||||||
#: For example: 'epub' or 'xml'
|
#: For example: 'epub' or 'xml'
|
||||||
file_types = set([])
|
file_types = set([])
|
||||||
|
|
||||||
@ -546,7 +546,7 @@ class CatalogPlugin(Plugin): # {{{
|
|||||||
def initialize(self):
|
def initialize(self):
|
||||||
'''
|
'''
|
||||||
If plugin is not a built-in, copy the plugin's .ui and .py files from
|
If plugin is not a built-in, copy the plugin's .ui and .py files from
|
||||||
the zip file to $TMPDIR.
|
the ZIP file to $TMPDIR.
|
||||||
Tab will be dynamically generated and added to the Catalog Options dialog in
|
Tab will be dynamically generated and added to the Catalog Options dialog in
|
||||||
calibre.gui2.dialogs.catalog.py:Catalog
|
calibre.gui2.dialogs.catalog.py:Catalog
|
||||||
'''
|
'''
|
||||||
|
@ -52,7 +52,7 @@ def find_plugin(name):
|
|||||||
|
|
||||||
def load_plugin(path_to_zip_file): # {{{
|
def load_plugin(path_to_zip_file): # {{{
|
||||||
'''
|
'''
|
||||||
Load plugin from zip file or raise InvalidPlugin error
|
Load plugin from ZIP file or raise InvalidPlugin error
|
||||||
|
|
||||||
:return: A :class:`Plugin` instance.
|
:return: A :class:`Plugin` instance.
|
||||||
'''
|
'''
|
||||||
@ -669,7 +669,7 @@ def initialize_plugin(plugin, path_to_zip_file):
|
|||||||
|
|
||||||
|
|
||||||
def has_external_plugins():
|
def has_external_plugins():
|
||||||
'True if there are updateable (zip file based) plugins'
|
'True if there are updateable (ZIP file based) plugins'
|
||||||
return bool(config['plugins'])
|
return bool(config['plugins'])
|
||||||
|
|
||||||
|
|
||||||
@ -756,10 +756,10 @@ def option_parser():
|
|||||||
Customize calibre by loading external plugins.
|
Customize calibre by loading external plugins.
|
||||||
'''))
|
'''))
|
||||||
parser.add_option('-a', '--add-plugin', default=None,
|
parser.add_option('-a', '--add-plugin', default=None,
|
||||||
help=_('Add a plugin by specifying the path to the zip file containing it.'))
|
help=_('Add a plugin by specifying the path to the ZIP file containing it.'))
|
||||||
parser.add_option('-b', '--build-plugin', default=None,
|
parser.add_option('-b', '--build-plugin', default=None,
|
||||||
help=_('For plugin developers: Path to the directory where you are'
|
help=_('For plugin developers: Path to the directory where you are'
|
||||||
' developing the plugin. This command will automatically zip '
|
' developing the plugin. This command will automatically ZIP '
|
||||||
'up the plugin and update it in calibre.'))
|
'up the plugin and update it in calibre.'))
|
||||||
parser.add_option('-r', '--remove-plugin', default=None,
|
parser.add_option('-r', '--remove-plugin', default=None,
|
||||||
help=_('Remove a custom plugin by name. Has no effect on builtin plugins'))
|
help=_('Remove a custom plugin by name. Has no effect on builtin plugins'))
|
||||||
|
@ -42,8 +42,8 @@ class ArchiveExtract(FileTypePlugin):
|
|||||||
name = 'Archive Extract'
|
name = 'Archive Extract'
|
||||||
author = 'Kovid Goyal'
|
author = 'Kovid Goyal'
|
||||||
description = _('Extract common e-book formats from archives '
|
description = _('Extract common e-book formats from archives '
|
||||||
'(zip/rar) files. Also try to autodetect if they are actually '
|
'(ZIP/RAR) files. Also try to autodetect if they are actually '
|
||||||
'cbz/cbr files.')
|
'CBZ/CBR files.')
|
||||||
file_types = set(['zip', 'rar'])
|
file_types = set(['zip', 'rar'])
|
||||||
supported_platforms = ['windows', 'osx', 'linux']
|
supported_platforms = ['windows', 'osx', 'linux']
|
||||||
on_import = True
|
on_import = True
|
||||||
@ -175,4 +175,3 @@ def get_comic_metadata(stream, stream_type, series_index='volume'):
|
|||||||
get_comic_book_info(m[cat], mi, series_index=series_index)
|
get_comic_book_info(m[cat], mi, series_index=series_index)
|
||||||
break
|
break
|
||||||
return mi
|
return mi
|
||||||
|
|
||||||
|
@ -279,10 +279,10 @@ class InterfaceAction(QObject):
|
|||||||
pixmap.loadFromData(self.load_resources(['images/icon.png']).itervalues().next())
|
pixmap.loadFromData(self.load_resources(['images/icon.png']).itervalues().next())
|
||||||
icon = QIcon(pixmap)
|
icon = QIcon(pixmap)
|
||||||
|
|
||||||
:param names: List of paths to resources in the zip file using / as separator
|
: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
|
: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
|
that were not found in the ZIP file will not be present in the
|
||||||
dictionary.
|
dictionary.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
@ -45,7 +45,7 @@ class ChoosePluginToolbarsDialog(QDialog):
|
|||||||
|
|
||||||
self._footer_label = QLabel(
|
self._footer_label = QLabel(
|
||||||
_('You can also customise the plugin locations '
|
_('You can also customise the plugin locations '
|
||||||
'using <b>Preferences -> Customise the toolbar</b>'))
|
'using <b>Preferences -> Interface -> Toolbars</b>'))
|
||||||
self._layout.addWidget(self._footer_label)
|
self._layout.addWidget(self._footer_label)
|
||||||
|
|
||||||
button_box = QDialogButtonBox(QDialogButtonBox.Ok |
|
button_box = QDialogButtonBox(QDialogButtonBox.Ok |
|
||||||
@ -60,4 +60,3 @@ class ChoosePluginToolbarsDialog(QDialog):
|
|||||||
for row in self._locations_list.selectionModel().selectedRows():
|
for row in self._locations_list.selectionModel().selectedRows():
|
||||||
selected.append(self.locations[row.row()])
|
selected.append(self.locations[row.row()])
|
||||||
return selected
|
return selected
|
||||||
|
|
||||||
|
@ -706,8 +706,8 @@ class PluginUpdaterDialog(SizePersistedDialog):
|
|||||||
|
|
||||||
plugin_zip_url = display_plugin.zip_url
|
plugin_zip_url = display_plugin.zip_url
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
prints('Downloading plugin zip attachment: ', plugin_zip_url)
|
prints('Downloading plugin ZIP attachment: ', plugin_zip_url)
|
||||||
self.gui.status_bar.showMessage(_('Downloading plugin zip attachment: %s') % plugin_zip_url)
|
self.gui.status_bar.showMessage(_('Downloading plugin ZIP attachment: %s') % plugin_zip_url)
|
||||||
zip_path = self._download_zip(plugin_zip_url)
|
zip_path = self._download_zip(plugin_zip_url)
|
||||||
|
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
|
@ -79,7 +79,7 @@ class UserDefinedDevice(QDialog):
|
|||||||
trailer = _(
|
trailer = _(
|
||||||
'Copy these values to the clipboard, paste them into an '
|
'Copy these values to the clipboard, paste them into an '
|
||||||
'editor, then enter them into the USER_DEVICE by '
|
'editor, then enter them into the USER_DEVICE by '
|
||||||
'customizing the device plugin in Preferences->Plugins. '
|
'customizing the device plugin in Preferences->Advanced->Plugins. '
|
||||||
'Remember to also enter the folders where you want the books to '
|
'Remember to also enter the folders where you want the books to '
|
||||||
'be put. You must restart calibre for your changes '
|
'be put. You must restart calibre for your changes '
|
||||||
'to take effect.\n')
|
'to take effect.\n')
|
||||||
@ -90,6 +90,7 @@ class UserDefinedDevice(QDialog):
|
|||||||
def copy_to_clipboard(self):
|
def copy_to_clipboard(self):
|
||||||
QApplication.clipboard().setText(self.log.toPlainText())
|
QApplication.clipboard().setText(self.log.toPlainText())
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app = QApplication([])
|
app = QApplication([])
|
||||||
d = UserDefinedDevice()
|
d = UserDefinedDevice()
|
||||||
|
@ -106,7 +106,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="close_button">
|
<widget class="QPushButton" name="close_button">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Close</string>
|
<string>&Close</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -75,7 +75,7 @@
|
|||||||
<item row="1" column="4">
|
<item row="1" column="4">
|
||||||
<widget class="QPushButton" name="close">
|
<widget class="QPushButton" name="close">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Close</string>
|
<string>&Close</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -154,4 +154,4 @@ def update_mark_text_action(ed=None):
|
|||||||
if ed is not None and ed.has_line_numbers:
|
if ed is not None and ed.has_line_numbers:
|
||||||
has_mark = bool(ed.selected_text) or not ed.has_marked_text
|
has_mark = bool(ed.selected_text) or not ed.has_marked_text
|
||||||
ac = actions['mark-selected-text']
|
ac = actions['mark-selected-text']
|
||||||
ac.setText(ac.default_text if has_mark else _('Unmark marked text'))
|
ac.setText(ac.default_text if has_mark else _('&Unmark marked text'))
|
||||||
|
@ -333,7 +333,7 @@ class Main(MainWindow):
|
|||||||
self.action_new_file = treg('document-new.png', _('&New file (images/fonts/HTML/etc.)'), self.boss.add_file,
|
self.action_new_file = treg('document-new.png', _('&New file (images/fonts/HTML/etc.)'), self.boss.add_file,
|
||||||
'new-file', (), _('Create a new file in the current book'))
|
'new-file', (), _('Create a new file in the current book'))
|
||||||
self.action_import_files = treg('document-import.png', _('&Import files into book'), self.boss.add_files, 'new-files', (), _('Import files into book'))
|
self.action_import_files = treg('document-import.png', _('&Import files into book'), self.boss.add_files, 'new-files', (), _('Import files into book'))
|
||||||
self.action_open_book = treg('document_open.png', _('Open &book'), self.boss.open_book, 'open-book', 'Ctrl+O', _('Open a new book'))
|
self.action_open_book = treg('document_open.png', _('&Open book'), self.boss.open_book, 'open-book', 'Ctrl+O', _('Open a new book'))
|
||||||
self.action_open_book_folder = treg('mimetypes/dir.png', _('Open &folder (unzipped EPUB) as book'), partial(self.boss.open_book, open_folder=True),
|
self.action_open_book_folder = treg('mimetypes/dir.png', _('Open &folder (unzipped EPUB) as book'), partial(self.boss.open_book, open_folder=True),
|
||||||
'open-folder-as-book', (), _('Open a folder (unzipped EPUB) as a book'))
|
'open-folder-as-book', (), _('Open a folder (unzipped EPUB) as a book'))
|
||||||
# Qt does not generate shortcut overrides for cmd+arrow on os x which
|
# Qt does not generate shortcut overrides for cmd+arrow on os x which
|
||||||
@ -445,7 +445,7 @@ class Main(MainWindow):
|
|||||||
'find', {'direction':'down'}, ('F3', 'Ctrl+G'), _('Find next match'))
|
'find', {'direction':'down'}, ('F3', 'Ctrl+G'), _('Find next match'))
|
||||||
self.action_find_previous = sreg('find-previous', _('Find &previous'),
|
self.action_find_previous = sreg('find-previous', _('Find &previous'),
|
||||||
'find', {'direction':'up'}, ('Shift+F3', 'Shift+Ctrl+G'), _('Find previous match'))
|
'find', {'direction':'up'}, ('Shift+F3', 'Shift+Ctrl+G'), _('Find previous match'))
|
||||||
self.action_replace = sreg('replace', _('Replace'),
|
self.action_replace = sreg('replace', _('&Replace'),
|
||||||
'replace', keys=('Ctrl+R'), description=_('Replace current match'))
|
'replace', keys=('Ctrl+R'), description=_('Replace current match'))
|
||||||
self.action_replace_next = sreg('replace-next', _('&Replace and find next'),
|
self.action_replace_next = sreg('replace-next', _('&Replace and find next'),
|
||||||
'replace-find', {'direction':'down'}, ('Ctrl+]'), _('Replace current match and find next'))
|
'replace-find', {'direction':'down'}, ('Ctrl+]'), _('Replace current match and find next'))
|
||||||
@ -461,7 +461,7 @@ class Main(MainWindow):
|
|||||||
self.action_go_to_line = reg(None, _('Go to &line'), self.boss.go_to_line_number, 'go-to-line-number', ('Ctrl+.',), _('Go to line number'))
|
self.action_go_to_line = reg(None, _('Go to &line'), self.boss.go_to_line_number, 'go-to-line-number', ('Ctrl+.',), _('Go to line number'))
|
||||||
self.action_saved_searches = treg('folder_saved_search.png', _('Sa&ved searches'),
|
self.action_saved_searches = treg('folder_saved_search.png', _('Sa&ved searches'),
|
||||||
self.boss.saved_searches, 'saved-searches', (), _('Show the saved searches dialog'))
|
self.boss.saved_searches, 'saved-searches', (), _('Show the saved searches dialog'))
|
||||||
self.action_text_search = treg('view.png', _('Search ignoring HTML markup'),
|
self.action_text_search = treg('view.png', _('&Search ignoring HTML markup'),
|
||||||
self.boss.show_text_search, 'text-search', (), _('Show the text search panel'))
|
self.boss.show_text_search, 'text-search', (), _('Show the text search panel'))
|
||||||
|
|
||||||
# Check Book actions
|
# Check Book actions
|
||||||
@ -566,7 +566,7 @@ class Main(MainWindow):
|
|||||||
e.addAction(self.action_set_semantics)
|
e.addAction(self.action_set_semantics)
|
||||||
e.addAction(self.action_filter_css)
|
e.addAction(self.action_filter_css)
|
||||||
e.addAction(self.action_spell_check_book)
|
e.addAction(self.action_spell_check_book)
|
||||||
er = e.addMenu(_('External links'))
|
er = e.addMenu(_('External &links'))
|
||||||
er.addAction(self.action_check_external_links)
|
er.addAction(self.action_check_external_links)
|
||||||
er.addAction(self.action_get_ext_resources)
|
er.addAction(self.action_get_ext_resources)
|
||||||
e.addAction(self.action_check_book)
|
e.addAction(self.action_check_book)
|
||||||
@ -617,7 +617,7 @@ class Main(MainWindow):
|
|||||||
e = b.addMenu(_('&Help'))
|
e = b.addMenu(_('&Help'))
|
||||||
a = e.addAction
|
a = e.addAction
|
||||||
a(self.action_help)
|
a(self.action_help)
|
||||||
a(QIcon(I('donate.png')), _('Donate to support calibre development'), open_donate)
|
a(QIcon(I('donate.png')), _('&Donate to support calibre development'), open_donate)
|
||||||
a(self.action_preferences)
|
a(self.action_preferences)
|
||||||
|
|
||||||
def search_menu_about_to_show(self):
|
def search_menu_about_to_show(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user