This commit is contained in:
Sengian 2011-01-29 00:14:00 +01:00
commit 649bae6933
22 changed files with 1109 additions and 822 deletions

View File

@ -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"

View File

@ -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/'),

View File

@ -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

View File

@ -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]},

View File

@ -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__',

View File

@ -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.')
),
])

View File

@ -197,14 +197,10 @@ def error_dialog(parent, title, msg, det_msg='', show=False,
return d.exec_()
return d
def question_dialog(parent, title, msg, det_msg='', show_copy_button=False,
buttons=None, yes_button=None):
def question_dialog(parent, title, msg, det_msg='', show_copy_button=False):
from calibre.gui2.dialogs.message_box import MessageBox
d = MessageBox(MessageBox.QUESTION, title, msg, det_msg, parent=parent,
show_copy_button=show_copy_button)
if buttons is not None:
d.bb.setStandardButtons(buttons)
return d.exec_() == d.Accepted
def info_dialog(parent, title, msg, det_msg='', show=False,

View File

@ -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():

View File

@ -7,7 +7,7 @@ import os, traceback, Queue, time, cStringIO, re, sys
from threading import Thread
from PyQt4.Qt import QMenu, QAction, QActionGroup, QIcon, SIGNAL, \
Qt, pyqtSignal, QDialog, QMessageBox
Qt, pyqtSignal, QDialog
from calibre.customize.ui import available_input_formats, available_output_formats, \
device_plugins
@ -609,10 +609,8 @@ class DeviceMixin(object): # {{{
autos = u'\n'.join(map(unicode, map(force_unicode, autos)))
return self.ask_a_yes_no_question(
_('No suitable formats'), msg,
buttons=QMessageBox.Yes|QMessageBox.Cancel,
ans_when_user_unavailable=True,
det_msg=autos,
show_copy_button=False
det_msg=autos
)
def set_default_thumbnail(self, height):

View File

@ -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)

View File

@ -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

View File

@ -92,7 +92,10 @@ class MessageBox(QDialog, Ui_Dialog):
def showEvent(self, ev):
ret = QDialog.showEvent(self, ev)
if self.is_question:
self.bb.button(self.bb.Yes).setFocus(Qt.OtherFocusReason)
try:
self.bb.button(self.bb.Yes).setFocus(Qt.OtherFocusReason)
except:
pass# Buttons were changed
else:
self.bb.button(self.bb.Ok).setFocus(Qt.OtherFocusReason)
return ret

View File

@ -7,7 +7,7 @@ import re, os
from PyQt4.Qt import Qt, QDialog, QGridLayout, QVBoxLayout, QFont, QLabel, \
pyqtSignal, QDialogButtonBox, QInputDialog, QLineEdit, \
QMessageBox, QDate
QDate
from calibre.gui2.dialogs.metadata_bulk_ui import Ui_MetadataBulkDialog
from calibre.gui2.dialogs.tag_editor import TagEditor
@ -15,7 +15,8 @@ from calibre.ebooks.metadata import string_to_authors, authors_to_string
from calibre.ebooks.metadata.book.base import composite_formatter
from calibre.ebooks.metadata.meta import get_metadata
from calibre.gui2.custom_column_widgets import populate_metadata_page
from calibre.gui2 import error_dialog, ResizableDialog, UNDEFINED_QDATE, gprefs
from calibre.gui2 import error_dialog, ResizableDialog, UNDEFINED_QDATE, \
gprefs, question_dialog
from calibre.gui2.progress_indicator import ProgressIndicator
from calibre.utils.config import dynamic, JSONConfig
from calibre.utils.titlecase import titlecase
@ -888,12 +889,9 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog):
if self.query_field.currentIndex() == 0:
return
ret = QMessageBox.question(self, _("Delete saved search/replace"),
if not question_dialog(self, _("Delete saved search/replace"),
_("The selected saved search/replace will be deleted. "
"Are you sure?"),
QMessageBox.Ok, QMessageBox.Cancel)
if ret == QMessageBox.Cancel:
"Are you sure?")):
return
item_id = self.query_field.currentIndex()
@ -917,11 +915,9 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog):
new = True
name = unicode(name)
if name in self.queries.keys():
ret = QMessageBox.question(self, _("Save search/replace"),
if not question_dialog(self, _("Save search/replace"),
_("That saved search/replace already exists and will be overwritten. "
"Are you sure?"),
QMessageBox.Ok, QMessageBox.Cancel)
if ret == QMessageBox.Cancel:
"Are you sure?")):
return
new = False

View File

@ -11,7 +11,7 @@ from functools import partial
from threading import Thread
from PyQt4.Qt import SIGNAL, QObject, Qt, QTimer, QDate, \
QPixmap, QListWidgetItem, QDialog, pyqtSignal, QMessageBox, QIcon, \
QPixmap, QListWidgetItem, QDialog, pyqtSignal, QIcon, \
QPushButton
from calibre.gui2 import error_dialog, file_icon_provider, dynamic, \
@ -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 '
@ -770,9 +770,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
if question_dialog(self, _('Tags changed'),
_('You have changed the tags. In order to use the tags'
' editor, you must either discard or apply these '
'changes'), show_copy_button=False,
buttons=QMessageBox.Apply|QMessageBox.Discard,
yes_button=QMessageBox.Apply):
'changes. Apply changes?'), show_copy_button=False):
self.apply_tags(commit=True, notify=True)
self.original_tags = unicode(self.tags.text())
else:

View File

@ -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()

View File

@ -4,7 +4,7 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
import sys, os, time, socket, traceback
from functools import partial
from PyQt4.Qt import QCoreApplication, QIcon, QMessageBox, QObject, QTimer, \
from PyQt4.Qt import QCoreApplication, QIcon, QObject, QTimer, \
QThread, pyqtSignal, Qt, QProgressDialog, QString, QPixmap, \
QSplashScreen, QApplication
@ -319,9 +319,6 @@ def run_gui(opts, args, actions, listener, app, gui_debug=None):
def cant_start(msg=_('If you are sure it is not running')+', ',
what=None):
d = QMessageBox(QMessageBox.Critical, _('Cannot Start ')+__appname__,
'<p>'+(_('%s is already running.')%__appname__)+'</p>',
QMessageBox.Ok)
base = '<p>%s</p><p>%s %s'
where = __appname__ + ' '+_('may be running in the system tray, in the')+' '
if isosx:
@ -334,8 +331,10 @@ def cant_start(msg=_('If you are sure it is not running')+', ',
else:
what = _('try deleting the file')+': '+ADDRESS
d.setInformativeText(base%(where, msg, what))
d.exec_()
info = base%(where, msg, what)
error_dialog(None, _('Cannot Start ')+__appname__,
'<p>'+(_('%s is already running.')%__appname__)+'</p>'+info, show=True)
raise SystemExit(1)
def communicate(args):

View File

@ -10,7 +10,7 @@ import textwrap, re, os
from PyQt4.Qt import Qt, QDateEdit, QDate, \
QIcon, QToolButton, QWidget, QLabel, QGridLayout, \
QDoubleSpinBox, QListWidgetItem, QSize, QPixmap, \
QPushButton, QSpinBox, QMessageBox, QLineEdit
QPushButton, QSpinBox, QLineEdit
from calibre.gui2.widgets import EnLineEdit, CompleteComboBox, \
EnComboBox, FormatList, ImageView, CompleteLineEdit
@ -848,9 +848,7 @@ class TagsEdit(CompleteLineEdit): # {{{
if question_dialog(self, _('Tags changed'),
_('You have changed the tags. In order to use the tags'
' editor, you must either discard or apply these '
'changes'), show_copy_button=False,
buttons=QMessageBox.Apply|QMessageBox.Discard,
yes_button=QMessageBox.Apply):
'changes. Apply changes?'), show_copy_button=False):
self.commit(db, id_)
db.commit()
self.original_val = self.current_val

View File

@ -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()

View File

@ -12,11 +12,9 @@ __docformat__ = 'restructuredtext en'
import collections, os, sys, textwrap, time
from Queue import Queue, Empty
from threading import Thread
from PyQt4.Qt import Qt, SIGNAL, QTimer, \
QPixmap, QMenu, QIcon, pyqtSignal, \
QDialog, \
QSystemTrayIcon, QApplication, QKeySequence, \
QMessageBox, QHelpEvent, QAction
from PyQt4.Qt import Qt, SIGNAL, QTimer, QHelpEvent, QAction, \
QMenu, QIcon, pyqtSignal, \
QDialog, QSystemTrayIcon, QApplication, QKeySequence
from calibre import prints
from calibre.constants import __appname__, isosx
@ -101,28 +99,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
@ -345,11 +355,12 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
def is_minimized_to_tray(self):
return getattr(self, '__systray_minimized', False)
def ask_a_yes_no_question(self, title, msg, **kwargs):
awu = kwargs.pop('ans_when_user_unavailable', True)
def ask_a_yes_no_question(self, title, msg, det_msg='',
show_copy_button=False, ans_when_user_unavailable=True):
if self.is_minimized_to_tray:
return awu
return question_dialog(self, title, msg, **kwargs)
return ans_when_user_unavailable
return question_dialog(self, title, msg, det_msg=det_msg,
show_copy_button=show_copy_button)
def hide_windows(self):
for window in QApplication.topLevelWidgets():
@ -589,11 +600,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
Quitting may cause corruption on the device.<br>
Are you sure you want to quit?''')+'</p>'
d = QMessageBox(QMessageBox.Warning, _('WARNING: Active jobs'), msg,
QMessageBox.Yes|QMessageBox.No, self)
d.setIconPixmap(QPixmap(I('dialog_warning.png')))
d.setDefaultButton(QMessageBox.No)
if d.exec_() != QMessageBox.Yes:
if not question_dialog(self, _('Active jobs'), msg):
return False
return True

View File

@ -53,8 +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: %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',
@ -230,8 +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: %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',

View File

@ -107,6 +107,7 @@ My device is not being detected by |app|?
Follow these steps to find the problem:
* Make sure that you are connecting only a single device to your computer at a time. Do not have another |app| supported device like an iPhone/iPad etc. at the same time.
* If you are connecting an Apple iDevice (iPad, iPod Touch, iPhone), use the 'Connect to iTunes' method in the 'Getting started' instructions in `Calibre + Apple iDevices: Start here <http://www.mobileread.com/forums/showthread.php?t=118559>`_.
* Make sure you are running the latest version of |app|. The latest version can always be downloaded from `the calibre website <http://calibre-ebook.com/download>`_.
* Ensure your operating system is seeing the device. That is, the device should be mounted as a disk that you can access using Windows explorer or whatever the file management program on your computer is.
* In calibre, go to Preferences->Plugins->Device Interface plugin and make sure the plugin for your device is enabled, the plugin icon next to it should be green when it is enabled.
@ -224,13 +225,12 @@ Replace ``192.168.1.2`` with the local IP address of the computer running |app|.
You wills ee a list of books in Safari, just click on the epub link for whichever book you want to read, Safari will then prompt you to open it with iBooks.
With the USB cable
With the USB cable + iTunes
^^^^^^^^^^^^^^^^^^^^^^^^^^^
As of |app| version 0.7.0, you can plug your iDevice into the computer using its charging cable, and |app| will detect it and show you a list of books on the device. You can then use the *Send to device button* to send books directly to iBooks on the device. Note that you must have at least iOS 4 installed on your iPhone/iTouch for this to work.
Use the 'Connect to iTunes' method in the 'Getting started' instructions in `Calibre + Apple iDevices: Start here <http://www.mobileread.com/forums/showthread.php?t=118559>`_.
This method only works on Windows XP and higher and OS X 10.5 and higher. Linux is not supported (iTunes is not available in linux) and OS X 10.4 is not supported.
For more details on how this works, see `this forum post <http://www.mobileread.com/forums/showpost.php?p=944079&postcount=1>`_.
This method only works on Windows XP and higher, and OS X 10.5 and higher. Linux is not supported (iTunes is not available in linux) and OS X 10.4 is not supported.
How do I use |app| with my Android phone?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

File diff suppressed because it is too large Load Diff