mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
0.7.43
This commit is contained in:
commit
8aea5df99c
129
Changelog.yaml
129
Changelog.yaml
@ -4,12 +4,137 @@
|
||||
# for important features/bug fixes.
|
||||
# Also, each release can have new and improved recipes.
|
||||
|
||||
#- version: ?.?.?
|
||||
# date: 2011-??-??
|
||||
#
|
||||
# new features:
|
||||
# - title:
|
||||
#
|
||||
# bug fixes:
|
||||
# - title:
|
||||
#
|
||||
# improved recipes:
|
||||
# -
|
||||
#
|
||||
# new recipes:
|
||||
# - title:
|
||||
|
||||
|
||||
- version: 0.7.43
|
||||
date: 2011-01-28
|
||||
|
||||
new features:
|
||||
- title: "Ask for confirmation when stopping running jobs"
|
||||
tickets: [3101]
|
||||
|
||||
- title: "Combine the database integrity check and library check into a single menu item. Also nicer implementation of the db integrity check."
|
||||
|
||||
- title: "BiBTeX Catalog: Add option to include file paths in the catalog."
|
||||
tickets: [8589]
|
||||
|
||||
- title: "Create 'generic' output profiles and generic devices in the welcome wizard"
|
||||
|
||||
- title: "Bulk metadata edit: Custom column widgets all have an apply checkbox next to them."
|
||||
|
||||
- title: "Only use LibraryThing to download metadata if the user provides a library thing username and password. Since LT doesn't like web scraping"
|
||||
|
||||
- title: "Allow renaming of user categories in the manage categories dialog. Also allow searching for books in a category from the Tag Browser by right clicking ona a category"
|
||||
|
||||
- title: "Folder device plugin: Add option to disable the use of sub folders"
|
||||
|
||||
- title: "Allow saving/loading of search and replace expressions in the bulk metadata edit dialog."
|
||||
|
||||
- title: "Remeber previously used regular expression in the add books preferences dialog"
|
||||
|
||||
- title: "Search and replace wizard: Cache the previously used input document."
|
||||
|
||||
- title: "Pressing Esc clears the current search in the main book list"
|
||||
|
||||
- title: "Preselct right formats when using send specific format to device"
|
||||
tickets: [7834]
|
||||
|
||||
- title: "Regex wizard gets find next and previous match buttons"
|
||||
tickets: [4486]
|
||||
|
||||
bug fixes:
|
||||
- title: "Do not allow customization of user interface plugins until calibre is restarted"
|
||||
tickets: [8621]
|
||||
|
||||
- title: "EPUB Output: When using preserve cover aspect ratio, use the actual image sizes in the SVG template as otherwise ADE doesn't fully preserve the aspect ratio"
|
||||
|
||||
- title: "Fix completion on a word with a trailing space causing the first letter to be duplicated in the edit metadata dialog"
|
||||
|
||||
- title: "PML Input: PML x and Xn tags don't indent properly in TOC. Also handle invalid T markup and retain soft scene breaks"
|
||||
tickets: [6194, 8565]
|
||||
|
||||
- title: "TXT Input: Retain whitespace at the beginning of lines. Don't preserve spaces in heuristic processing. Detect and retain soft scene breaks."
|
||||
|
||||
- title: "Fix Adding empty book - cover browser doesn't update"
|
||||
tickets: [8557]
|
||||
|
||||
- title: "When generating author sort string ignore trailing Inc."
|
||||
tickets: [8539]
|
||||
|
||||
- title: "When converting HTML/ZIP files do not leave temporary files that are only deleted on application shutdown."
|
||||
tickets: [8597]
|
||||
|
||||
- title: "Don't crash if the prefs stored in the db are corrupted"
|
||||
|
||||
- title: "Catalog generation: Do not use inline-block CSS as apparently Adobe Digital Editions cannot handle it."
|
||||
tickets: [8566]
|
||||
|
||||
- title: "Fix extra spaces being inserted into TOC title when reading TOC from OPF guide element."
|
||||
tickets: [8569]
|
||||
|
||||
- title: "Remember window size for bulk metadata edit and catalog generation dialogs"
|
||||
tickets: [8525]
|
||||
|
||||
- title: "Heuristics, italicize common cases: Enhance pattern matching to match punctuation after pattern."
|
||||
|
||||
- title: "Fix regression in converting HTML files that have ASCII-encoded non unicode characters inside their <style> tags. Apparently Word generates these."
|
||||
tickets: [8494]
|
||||
|
||||
improved recipes:
|
||||
- Calgary Herald
|
||||
- The Economist
|
||||
- New Yorker
|
||||
- Heise
|
||||
- HNA
|
||||
- ZDNet
|
||||
- NRC Handelsblad
|
||||
|
||||
new recipes:
|
||||
- title: "SPIN Magazine"
|
||||
author: Quistopher
|
||||
|
||||
- title: "Caps n Babes"
|
||||
author: skyhawker
|
||||
|
||||
- title: "Leduc"
|
||||
author: Brian Hahn
|
||||
|
||||
- title: "David Bravo's Blog, La Nueva Espana, 20 Minutos and La Tribuna de Talavera"
|
||||
author: Luis Hernandez
|
||||
|
||||
- title: "Sinfest"
|
||||
author: nadid
|
||||
|
||||
- title: "Various Czech news sources"
|
||||
author: FunThomas
|
||||
|
||||
- title: "tportal.h"
|
||||
author: Darko Miletic
|
||||
|
||||
- title: "Everett Herald"
|
||||
author: "77jag5"
|
||||
|
||||
- title: "Roger Ebert"
|
||||
author: Shane Erstad
|
||||
|
||||
- version: 0.7.42
|
||||
date: 2011-01-21
|
||||
|
||||
new features:
|
||||
- title: "0.7.42 is a re-release of 0.7.41, because conversion to MOBI was broken in 0.7.41"
|
||||
|
||||
- title: "Conversions: Replace the remove header/footer options with a more geenric search replace option, that allows you to not only remove but also replace text"
|
||||
|
||||
- title: "Conversion: The preprocess html option has now become a new 'Heuristic Processing' option which allows you to control exactly which heuristics are used"
|
||||
|
@ -26,7 +26,7 @@ class BBC(BasicNewsRecipe):
|
||||
extra_css = '.headline {font-size: x-large;} \n .fact { padding-top: 10pt }'
|
||||
|
||||
feeds = [
|
||||
('Interviews', 'http://www.avclub.com/feed/interview/'),
|
||||
('TV', 'http://www.avclub.com/feed/tv/'),
|
||||
('AV Club Daily', 'http://www.avclub.com/feed/daily'),
|
||||
('Film', 'http://www.avclub.com/feed/film/'),
|
||||
('Music', 'http://www.avclub.com/feed/music/'),
|
||||
|
@ -2,7 +2,7 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
__appname__ = 'calibre'
|
||||
__version__ = '0.7.42'
|
||||
__version__ = '0.7.43'
|
||||
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
|
||||
|
||||
import re
|
||||
|
@ -19,7 +19,8 @@ class ANDROID(USBMS):
|
||||
|
||||
VENDOR_ID = {
|
||||
# HTC
|
||||
0x0bb4 : { 0x0c02 : [0x100, 0x0227, 0x0226], 0x0c01 : [0x100, 0x0227], 0x0ff9
|
||||
0x0bb4 : { 0x0c02 : [0x100, 0x0227, 0x0226], 0x0c01 : [0x100,
|
||||
0x0227, 0x0226], 0x0ff9
|
||||
: [0x0100, 0x0227, 0x0226], 0x0c87: [0x0100, 0x0227, 0x0226],
|
||||
0xc92 : [0x100], 0xc97: [0x226], 0xc99 : [0x0100]},
|
||||
|
||||
|
@ -141,8 +141,8 @@ class CoverManager(object):
|
||||
if width is None or height is None:
|
||||
self.log.warning('Failed to read cover dimensions')
|
||||
width, height = 600, 800
|
||||
if self.preserve_aspect_ratio:
|
||||
width, height = 600, 800
|
||||
#if self.preserve_aspect_ratio:
|
||||
# width, height = 600, 800
|
||||
self.svg_template = self.svg_template.replace('__viewbox__',
|
||||
'0 0 %d %d'%(width, height))
|
||||
self.svg_template = self.svg_template.replace('__width__',
|
||||
|
@ -47,7 +47,7 @@ class PDFOutput(OutputFormatPlugin):
|
||||
OptionRecommendation(name='preserve_cover_aspect_ratio',
|
||||
recommended_value=False,
|
||||
help=_('Preserve the aspect ratio of the cover, instead'
|
||||
' of stretching it to fill the ull first page of the'
|
||||
' of stretching it to fill the full first page of the'
|
||||
' generated pdf.')
|
||||
),
|
||||
])
|
||||
|
@ -295,8 +295,12 @@ class ChooseLibraryAction(InterfaceAction):
|
||||
return error_dialog(self.gui, _('Failed'),
|
||||
_('Database integrity check failed, click Show details'
|
||||
' for details.'), show=True, det_msg=d.error[1])
|
||||
|
||||
d = CheckLibraryDialog(self.gui, m.db)
|
||||
d.exec_()
|
||||
if not d.do_exec():
|
||||
info_dialog(self.gui, _('No problems found'),
|
||||
_('The files in your library match the information '
|
||||
'in the database.'), show=True)
|
||||
|
||||
def switch_requested(self, location):
|
||||
if not self.change_library_allowed():
|
||||
|
@ -139,7 +139,7 @@ class CheckLibraryDialog(QDialog):
|
||||
QDialog.__init__(self, parent)
|
||||
self.db = db
|
||||
|
||||
self.setWindowTitle(_('Check Library'))
|
||||
self.setWindowTitle(_('Check Library -- Problems Found'))
|
||||
|
||||
self._layout = QVBoxLayout(self)
|
||||
self.setLayout(self._layout)
|
||||
@ -148,7 +148,7 @@ class CheckLibraryDialog(QDialog):
|
||||
self.log.itemChanged.connect(self.item_changed)
|
||||
self._layout.addWidget(self.log)
|
||||
|
||||
self.check_button = QPushButton(_('&Run the check'))
|
||||
self.check_button = QPushButton(_('&Run the check again'))
|
||||
self.check_button.setDefault(False)
|
||||
self.check_button.clicked.connect(self.run_the_check)
|
||||
self.copy_button = QPushButton(_('Copy &to clipboard'))
|
||||
@ -196,8 +196,17 @@ class CheckLibraryDialog(QDialog):
|
||||
self.resize(750, 500)
|
||||
self.bbox.setEnabled(True)
|
||||
|
||||
def do_exec(self):
|
||||
self.run_the_check()
|
||||
|
||||
probs = 0
|
||||
for c in self.problem_count:
|
||||
probs += self.problem_count[c]
|
||||
if probs == 0:
|
||||
return False
|
||||
self.exec_()
|
||||
return True
|
||||
|
||||
def accept(self):
|
||||
self.db.prefs['check_library_ignore_extensions'] = \
|
||||
unicode(self.ext_ignores.text())
|
||||
@ -219,7 +228,10 @@ class CheckLibraryDialog(QDialog):
|
||||
attr, h, checkable, fixable = check
|
||||
list = getattr(checker, attr, None)
|
||||
if list is None:
|
||||
self.problem_count[attr] = 0
|
||||
return
|
||||
else:
|
||||
self.problem_count[attr] = len(list)
|
||||
|
||||
tl = Item()
|
||||
tl.setText(0, h)
|
||||
@ -250,6 +262,7 @@ class CheckLibraryDialog(QDialog):
|
||||
t.setHeaderLabels([_('Name'), _('Path from library')])
|
||||
self.all_items = []
|
||||
self.top_level_items = {}
|
||||
self.problem_count = {}
|
||||
for check in CHECKS:
|
||||
builder(t, checker, check)
|
||||
|
||||
|
@ -21,10 +21,10 @@ class Dialog(QDialog, Ui_Dialog):
|
||||
self.again.stateChanged.connect(self.toggle)
|
||||
self.buttonBox.setFocus(Qt.OtherFocusReason)
|
||||
|
||||
|
||||
def toggle(self, *args):
|
||||
dynamic[_config_name(self.name)] = self.again.isChecked()
|
||||
|
||||
|
||||
def confirm(msg, name, parent=None, pixmap='dialog_warning.png'):
|
||||
if not dynamic.get(_config_name(name), True):
|
||||
return True
|
||||
|
@ -209,7 +209,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
|
||||
title = unicode(self.title.text()).strip()
|
||||
author = unicode(self.authors.text()).strip()
|
||||
if author.endswith('&'):
|
||||
author = author[:-1]
|
||||
author = author[:-1].strip()
|
||||
if not title or not author:
|
||||
return error_dialog(self, _('Specify title and author'),
|
||||
_('You must specify a title and author before generating '
|
||||
|
@ -19,7 +19,7 @@ from PyQt4.Qt import QAbstractTableModel, QVariant, QModelIndex, Qt, \
|
||||
|
||||
from calibre.utils.ipc.server import Server
|
||||
from calibre.utils.ipc.job import ParallelJob
|
||||
from calibre.gui2 import Dispatcher, error_dialog, NONE, config, gprefs
|
||||
from calibre.gui2 import Dispatcher, error_dialog, question_dialog, NONE, config, gprefs
|
||||
from calibre.gui2.device import DeviceJob
|
||||
from calibre.gui2.dialogs.jobs_ui import Ui_JobsDialog
|
||||
from calibre import __appname__
|
||||
@ -380,8 +380,8 @@ class JobsDialog(QDialog, Ui_JobsDialog):
|
||||
self.model = model
|
||||
self.setWindowModality(Qt.NonModal)
|
||||
self.setWindowTitle(__appname__ + _(' - Jobs'))
|
||||
self.kill_button.clicked.connect(self.kill_job)
|
||||
self.details_button.clicked.connect(self.show_details)
|
||||
self.kill_button.clicked.connect(self.kill_job)
|
||||
self.stop_all_jobs_button.clicked.connect(self.kill_all_jobs)
|
||||
self.pb_delegate = ProgressBarDelegate(self)
|
||||
self.jobs_view.setItemDelegateForColumn(2, self.pb_delegate)
|
||||
@ -415,19 +415,20 @@ class JobsDialog(QDialog, Ui_JobsDialog):
|
||||
d.exec_()
|
||||
d.timer.stop()
|
||||
|
||||
def kill_job(self, *args):
|
||||
for index in self.jobs_view.selectedIndexes():
|
||||
row = index.row()
|
||||
self.model.kill_job(row, self)
|
||||
return
|
||||
|
||||
def show_details(self, *args):
|
||||
for index in self.jobs_view.selectedIndexes():
|
||||
self.show_job_details(index)
|
||||
return
|
||||
|
||||
def kill_job(self, *args):
|
||||
if question_dialog(self, _('Are you sure?'), _('Do you really want to stop the selected job?')):
|
||||
for index in self.jobs_view.selectedIndexes():
|
||||
row = index.row()
|
||||
self.model.kill_job(row, self)
|
||||
|
||||
def kill_all_jobs(self, *args):
|
||||
self.model.kill_all_jobs()
|
||||
if question_dialog(self, _('Are you sure?'), _('Do you really want to stop all non-device jobs?')):
|
||||
self.model.kill_all_jobs()
|
||||
|
||||
def closeEvent(self, e):
|
||||
self.save_state()
|
||||
|
@ -188,6 +188,9 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
self.plugin_view.PositionAtCenter)
|
||||
self.plugin_view.scrollTo(idx,
|
||||
self.plugin_view.PositionAtCenter)
|
||||
self.plugin_view.selectionModel().select(idx,
|
||||
self.plugin_view.selectionModel().ClearAndSelect)
|
||||
self.plugin_view.setCurrentIndex(idx)
|
||||
else:
|
||||
error_dialog(self, _('No valid plugin path'),
|
||||
_('%s is not a valid plugin path')%path).exec_()
|
||||
@ -220,10 +223,16 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
_('Plugin: %s does not need customization')%plugin.name).exec_()
|
||||
return
|
||||
self.changed_signal.emit()
|
||||
from calibre.customize import InterfaceActionBase
|
||||
if isinstance(plugin, InterfaceActionBase) and not getattr(plugin,
|
||||
'actual_iaction_plugin_loaded', False):
|
||||
return error_dialog(self, _('Must restart'),
|
||||
_('You must restart calibre before you can'
|
||||
' configure the <b>%s</b> plugin')%plugin.name, show=True)
|
||||
if plugin.do_user_config():
|
||||
self._plugin_model.refresh_plugin(plugin)
|
||||
elif op == 'remove':
|
||||
msg = _('Plugin {0} successfully removed').format(plugin.name)
|
||||
msg = _('Plugin <b>{0}</b> successfully removed').format(plugin.name)
|
||||
if remove_plugin(plugin):
|
||||
self._plugin_model.populate()
|
||||
self._plugin_model.reset()
|
||||
|
@ -101,28 +101,40 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
|
||||
self.opts = opts
|
||||
self.device_connected = None
|
||||
self.gui_debug = gui_debug
|
||||
acmap = OrderedDict()
|
||||
self.iactions = OrderedDict()
|
||||
for action in interface_actions():
|
||||
if opts.ignore_plugins and action.plugin_path is not None:
|
||||
continue
|
||||
try:
|
||||
ac = action.load_actual_plugin(self)
|
||||
ac = self.init_iaction(action)
|
||||
except:
|
||||
# Ignore errors in loading user supplied plugins
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
if ac.plugin_path is None:
|
||||
if action.plugin_path is None:
|
||||
raise
|
||||
continue
|
||||
|
||||
ac.plugin_path = action.plugin_path
|
||||
ac.interface_action_base_plugin = action
|
||||
if ac.name in acmap:
|
||||
if ac.priority >= acmap[ac.name].priority:
|
||||
acmap[ac.name] = ac
|
||||
else:
|
||||
acmap[ac.name] = ac
|
||||
|
||||
self.iactions = acmap
|
||||
self.add_iaction(ac)
|
||||
|
||||
def init_iaction(self, action):
|
||||
ac = action.load_actual_plugin(self)
|
||||
ac.plugin_path = action.plugin_path
|
||||
ac.interface_action_base_plugin = action
|
||||
action.actual_iaction_plugin_loaded = True
|
||||
return ac
|
||||
|
||||
def add_iaction(self, ac):
|
||||
acmap = self.iactions
|
||||
if ac.name in acmap:
|
||||
if ac.priority >= acmap[ac.name].priority:
|
||||
acmap[ac.name] = ac
|
||||
else:
|
||||
acmap[ac.name] = ac
|
||||
|
||||
|
||||
def initialize(self, library_path, db, listener, actions, show_gui=True):
|
||||
opts = self.opts
|
||||
|
@ -53,9 +53,10 @@ class CSV_XML(CatalogPlugin): # {{{
|
||||
'database. Should be a comma-separated list of fields.\n'
|
||||
'Available fields: %s,\n'
|
||||
'plus user-created custom fields.\n'
|
||||
'Example: --fields=title,authors,tags\n'
|
||||
'Example: %s=title,authors,tags\n'
|
||||
"Default: '%%default'\n"
|
||||
"Applies to: CSV, XML output formats")%', '.join(FIELDS)),
|
||||
"Applies to: CSV, XML output formats")%(', '.join(FIELDS),
|
||||
'--fields')),
|
||||
|
||||
Option('--sort-by',
|
||||
default = 'id',
|
||||
@ -231,9 +232,10 @@ class BIBTEX(CatalogPlugin): # {{{
|
||||
help = _('The fields to output when cataloging books in the '
|
||||
'database. Should be a comma-separated list of fields.\n'
|
||||
'Available fields: %s.\n'
|
||||
'Example: --fields=title,authors,tags\n'
|
||||
'Example: %s=title,authors,tags\n'
|
||||
"Default: '%%default'\n"
|
||||
"Applies to: BIBTEX output format")%', '.join(FIELDS)),
|
||||
"Applies to: BIBTEX output format")%(', '.join(FIELDS),
|
||||
'--fields')),
|
||||
|
||||
Option('--sort-by',
|
||||
default = 'id',
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user