Merge from trunk

This commit is contained in:
Sengian 2010-12-17 21:40:56 +01:00
commit d9b79fb481
37 changed files with 1853 additions and 1223 deletions

View File

@ -4,6 +4,126 @@
# for important features/bug fixes.
# Also, each release can have new and improved recipes.
- version: 0.7.34
date: 2010-12-17
new features:
- title: "Page turn animations in the e-book viewer"
type: major
description: >
"Now when you use the Page Down/Page Up keys or the next/previous page buttons in the viewer, page turning will be animated. The duration of the animation can be controlled in the viewer preferences. Setting it to o disables the animation completely."
- title: "Conversion pipeline: Add an option to set the minimum line height of all elemnts as a percentage of the computed font size. By default, calibre now sets the line height to 120% of the computed font size."
- title: "Large speedup in startup times and post metadata edit wait for large libraries"
- title: "Allow changing the font used in the calibre interface via Preferences->Look and feel"
- title: "Allow editing of the title sort value for a book via the edit metadata dialog"
- title: "Disable the cover cache. This means that if you are running calibre on an underpowered machine, you might notice some slow down in the cover browser. On the other hand, calibre's memory consumption is reduced."
- title: "You can now restart calibre in debug mode by clicking the arrow next to the Preferences button. In debug mode, after you quit calibre, a diagnostic log will popup"
tickets: [7359]
- title: "When creating a new calibre library add an option to copy the custom column, saved searches, etc from the current library."
tickets: [7643]
- title: "Add more tweaks to control how the next available series number is calculated."
tickets: [7892]
- title: "Add a tweak to control layout of the custom metadata tab in the edit metadata dialog"
- title: "Apple driver: Set series number as track number on windows when sending books to iTunes"
- title: "Drivers for PocketBook 701 and Samsung E65"
- title: "E-book viewer: Add option to have the mouse wheel flip pages"
- title: "Add a load_resources method to the InterfaceAction and Plugin classes to facilitate loading of resources from plugin ZIP files"
- title: "E-book viewer: Add option to not remember position in book when quitting."
tickets: [7699]
- title: "When sorting the book list, keep the current book visible after the sort completes."
tickets: [7504]
- title: "EPUB Output: Add an option to flatten the EPUB file structure, specially for FBReaderJ."
tickets: [7788]
- title: "EPUB Output: Ensure all files inside the generated EPUB have unique filenames, to support broken EPUB readers like Stanza, Aldiko, FBReader and Sigil"
- title: "FB2 Output: Add support for some 2.1 style tags."
- title: "Bulk metadata edit: Add options to delete cover/generate default cover."
tickets: [7885]
- title: "Fix a regression in 0.7.33 that broke updating covers in ebook files when saving to disk."
tickets: [7886]
- title: "Don't refresh the Tag browser if it is hidden. Speeds up metadata editing with large libraries, if you hide teh Tag Browser."
- title: "MOBI Output: Add option to ignore margins in input document"
tickets: [7877]
- title: "Kobo driver: Add support for 1.8.x firmware"
bug fixes:
- title: "Fix various memory leaks introduced in the last couple of releases"
- title: "EPUB metadata: When rendering first page as the cover, handle embedded svg correctly."
tickets: [7909]
- title: "Disable multiple library support when the CALIBRE_OVERRIDE_DATABASE_PATH env var is set"
- title: "Content server: Fix bug that could cause saved search based restrictions to not exclude all books"
tickets: [7876]
- title: "Topaz metadata: Read metadata correctly from Topaz files that have MOBI file extensions"
- title: "MOBI Input: Handle the (rare) MOBI files that do not specify per paragraph text indents correctly."
tickets: [7869]
- title: "MOBI metadata reader: Handle invalid PRC files with spurious image_offset headers"
- title: "Fix drag/drop of new cover to book detail panel does not update cover browser"
tickets: [7890]
- title: "Do not open the book details dialog when double click on the scrollbars in the book details panel"
tickets: [7826]
- title: "Templates: Fix {tags} not working when no tags are present"
tickets: [7888]
- title: "HTML metadata: Fix regression that broke parsing of some meta tags"
tickets: [7851]
- title: "Preferences: Add tooltips to buddy labels as well."
tickets: [7873]
- title: "Content server: Fix handling of root URL when using --url-prefix"
- title: "Ensure that the default encoding used by python is never ASCII (needed when running a non frozen version of calibre on linux)"
improved recipes:
- Astronomy Picture of the day
- New Scientist
- Radikal
- Times of India
- Economic Times
- Zeit Online
- Dilbert
new recipes:
- title: "Various Japanes news sources, National Geographic and paper.li"
author: "Hiroshi Miura"
- title: "Science based medicine"
author: "BuzzKill"
- title: "Kompiutierra"
author: "Vadim Dyadkin"
- version: 0.7.33
date: 2010-12-10

View File

@ -12,13 +12,24 @@ defaults.
# The algorithm used to assign a new book in an existing series a series number.
# New series numbers assigned using this tweak are always integer values, except
# if a constant non-integer is specified.
# Possible values are:
# next - Next available number
# next - First available integer larger than the largest existing number
# first_free - First available integer larger than 0
# next_free - First available integer larger than the smallest existing number
# last_free - First available integer smaller than the largest existing number
# Return largest existing + 1 if no free number is found
# const - Assign the number 1 always
# a number - Assign that number always. The number is not in quotes. Note that
# 0.0 can be used here.
# Examples:
# series_index_auto_increment = 'next'
# series_index_auto_increment = 'next_free'
# series_index_auto_increment = 16.5
series_index_auto_increment = 'next'
# The algorithm used to copy author to author_sort
# Possible values are:
# invert: use "fn ln" -> "ln, fn" (the original algorithm)
@ -235,3 +246,9 @@ doubleclick_on_library_view = 'open_viewer'
# Example: locale_for_sorting = 'fr' -- sort using French rules.
# Example: locale_for_sorting = 'nb' -- sort using Norwegian rules.
locale_for_sorting = ''
# Set whether to use one or two columns for custom metadata when editing
# metadata one book at a time. If True, then the fields are laid out using two
# columns. If False, one column is used.
metadata_single_use_2_cols_for_custom_fields = True

View File

@ -11,6 +11,7 @@ class APOD(BasicNewsRecipe):
remove_javascript = True
recursions = 0
oldest_article = 14
remove_attributes = ['onmouseover', 'onmouseout']
feeds = [
(u'Astronomy Picture of the Day', u'http://apod.nasa.gov/apod.rss')

View File

@ -2,7 +2,7 @@ __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
__docformat__ = 'restructuredtext en'
__appname__ = 'calibre'
__version__ = '0.7.33'
__version__ = '0.7.34'
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
import re

View File

@ -23,6 +23,12 @@ Run an embedded python interpreter.
help='Debug the specified device driver.')
parser.add_option('-g', '--gui', default=False, action='store_true',
help='Run the GUI',)
parser.add_option('--gui-debug', default=None,
help='Run the GUI with a debug console, logging to the'
' specified path',)
parser.add_option('--show-gui-debug', default=None,
help='Display the specified log file.',)
parser.add_option('-w', '--viewer', default=False, action='store_true',
help='Run the ebook viewer',)
parser.add_option('--paths', default=False, action='store_true',
@ -135,7 +141,28 @@ def add_simple_plugin(path_to_plugin):
os.chdir(odir)
shutil.rmtree(tdir)
def run_debug_gui(logpath):
import time, platform
time.sleep(3) # Give previous GUI time to shutdown fully and release locks
from calibre.constants import __appname__, __version__, isosx
print __appname__, _('Debug log')
print __appname__, __version__
print platform.platform()
print platform.system()
print platform.system_alias(platform.system(), platform.release(),
platform.version())
print 'Python', platform.python_version()
try:
if iswindows:
print 'Windows:', platform.win32_ver()
elif isosx:
print 'OSX:', platform.mac_ver()
else:
print 'Linux:', platform.linux_distribution()
except:
pass
from calibre.gui2.main import main
main(['__CALIBRE_GUI_DEBUG__', logpath])
def main(args=sys.argv):
from calibre.constants import debug
@ -154,6 +181,20 @@ def main(args=sys.argv):
if opts.gui:
from calibre.gui2.main import main
main(['calibre'])
elif opts.gui_debug is not None:
run_debug_gui(opts.gui_debug)
elif opts.show_gui_debug:
import time, re
time.sleep(1)
from calibre.gui2 import open_local_file
if iswindows:
with open(opts.show_gui_debug, 'r+b') as f:
raw = f.read()
raw = re.sub('(?<!\r)\n', '\r\n', raw)
f.seek(0)
f.truncate()
f.write(raw)
open_local_file(opts.show_gui_debug)
elif opts.viewer:
from calibre.gui2.viewer.main import main
vargs = ['ebook-viewer', '--debug-javascript']

View File

@ -96,7 +96,7 @@ class KOBO(USBMS):
for idx,b in enumerate(bl):
bl_cache[b.lpath] = idx
def update_booklist(prefix, path, title, authors, mime, date, ContentType, ImageID, readstatus):
def update_booklist(prefix, path, title, authors, mime, date, ContentType, ImageID, readstatus, MimeType):
changed = False
# if path_to_ext(path) in self.FORMATS:
try:
@ -124,7 +124,7 @@ class KOBO(USBMS):
#print "Image name Normalized: " + imagename
if imagename is not None:
bl[idx].thumbnail = ImageWrapper(imagename)
if (ContentType != '6'and self.has_kepubs == False) or (self.has_kepubs == True):
if (ContentType != '6' and MimeType != 'Shortcover'):
if self.update_metadata_item(bl[idx]):
# print 'update_metadata_item returned true'
changed = True
@ -132,7 +132,7 @@ class KOBO(USBMS):
playlist_map[lpath] not in bl[idx].device_collections:
bl[idx].device_collections.append(playlist_map[lpath])
else:
if ContentType == '6' and self.has_kepubs == False:
if ContentType == '6' and MimeType == 'Shortcover':
book = Book(prefix, lpath, title, authors, mime, date, ContentType, ImageID, size=1048576)
else:
try:
@ -177,15 +177,15 @@ class KOBO(USBMS):
for i, row in enumerate(cursor):
# self.report_progress((i+1) / float(numrows), _('Getting list of books on device...'))
path = self.path_from_contentid(row[3], row[5], oncard)
path = self.path_from_contentid(row[3], row[5], row[4], oncard)
mime = mime_type_ext(path_to_ext(path)) if path.find('kepub') == -1 else 'application/epub+zip'
# debug_print("mime:", mime)
if oncard != 'carda' and oncard != 'cardb' and not row[3].startswith("file:///mnt/sd/"):
changed = update_booklist(self._main_prefix, path, row[0], row[1], mime, row[2], row[5], row[6], row[7])
changed = update_booklist(self._main_prefix, path, row[0], row[1], mime, row[2], row[5], row[6], row[7], row[4])
# print "shortbook: " + path
elif oncard == 'carda' and row[3].startswith("file:///mnt/sd/"):
changed = update_booklist(self._card_a_prefix, path, row[0], row[1], mime, row[2], row[5], row[6], row[7])
changed = update_booklist(self._card_a_prefix, path, row[0], row[1], mime, row[2], row[5], row[6], row[7], row[4])
if changed:
need_sync = True
@ -363,7 +363,8 @@ class KOBO(USBMS):
def contentid_from_path(self, path, ContentType):
if ContentType == 6:
if self.has_kepubs == False:
extension = os.path.splitext(path)[1]
if extension == '.kobo':
ContentID = os.path.splitext(path)[0]
# Remove the prefix on the file. it could be either
ContentID = ContentID.replace(self._main_prefix, '')
@ -411,7 +412,7 @@ class KOBO(USBMS):
ContentType = 999 # Yet another hack: to get around Kobo changing how ContentID is stored
return ContentType
def path_from_contentid(self, ContentID, ContentType, oncard):
def path_from_contentid(self, ContentID, ContentType, MimeType, oncard):
path = ContentID
if oncard == 'cardb':
@ -420,13 +421,13 @@ class KOBO(USBMS):
path = path.replace("file:///mnt/sd/", self._card_a_prefix)
# print "SD Card: " + path
else:
if ContentType == "6" and self.has_kepubs == False:
if ContentType == "6" and MimeType == 'Shortcover':
# This is a hack as the kobo files do not exist
# but the path is required to make a unique id
# for calibre's reference
path = self._main_prefix + path + '.kobo'
# print "Path: " + path
elif (ContentType == "6" or ContentType == "10") and self.has_kepubs == True:
elif (ContentType == "6" or ContentType == "10") and MimeType == 'application/x-kobo-epub+zip':
path = self._main_prefix + '.kobo/kepub/' + path
# print "Internal: " + path
else:

View File

@ -10,6 +10,7 @@ from PyQt4.Qt import QIcon, QMenu, Qt
from calibre.gui2.actions import InterfaceAction
from calibre.gui2.preferences.main import Preferences
from calibre.gui2 import error_dialog
from calibre.constants import DEBUG
class PreferencesAction(InterfaceAction):
@ -22,6 +23,10 @@ class PreferencesAction(InterfaceAction):
pm.addAction(QIcon(I('config.png')), _('Preferences'), self.do_config)
pm.addAction(QIcon(I('wizard.png')), _('Run welcome wizard'),
self.gui.run_wizard)
if not DEBUG:
pm.addSeparator()
pm.addAction(QIcon(I('debug.png')), _('Restart in debug mode'),
self.debug_restart)
self.qaction.setMenu(pm)
self.preferences_menu = pm
for x in (self.gui.preferences_action, self.qaction):
@ -44,4 +49,6 @@ class PreferencesAction(InterfaceAction):
d.run_wizard_requested.connect(self.gui.run_wizard,
type=Qt.QueuedConnection)
def debug_restart(self, *args):
self.gui.quit(restart=True, debug_on_restart=True)

View File

@ -303,7 +303,7 @@ class Series(Base):
if val == '':
val = s_index = None
elif s_index == 0.0:
if tweaks['series_index_auto_increment'] == 'next':
if tweaks['series_index_auto_increment'] != 'const':
s_index = self.db.get_next_cc_series_num_for(val,
num=self.col_id)
else:
@ -572,7 +572,6 @@ class BulkSeries(BulkBase):
val = None if clear else self.normalize_ui_val(val)
if clear or val != '':
extras = []
next_index = self.db.get_next_cc_series_num_for(val, num=self.col_id)
for book_id in book_ids:
if clear:
extras.append(None)
@ -581,9 +580,8 @@ class BulkSeries(BulkBase):
if force_start:
s_index = at_value
at_value += 1
elif tweaks['series_index_auto_increment'] == 'next':
s_index = next_index
next_index += 1
elif tweaks['series_index_auto_increment'] != 'const':
s_index = self.db.get_next_cc_series_num_for(val, num=self.col_id)
else:
s_index = 1.0
else:

View File

@ -32,6 +32,11 @@ class ChooseLibrary(QDialog, Ui_Dialog):
loc = unicode(self.old_location.text()).format(lp)
self.old_location.setText(loc)
self.browse_button.clicked.connect(self.choose_loc)
self.empty_library.toggled.connect(self.empty_library_toggled)
self.copy_structure.setEnabled(False)
def empty_library_toggled(self, to_what):
self.copy_structure.setEnabled(to_what)
def choose_loc(self, *args):
loc = choose_dir(self, 'choose library location',
@ -64,7 +69,7 @@ class ChooseLibrary(QDialog, Ui_Dialog):
def perform_action(self, ac, loc):
if ac in ('new', 'existing'):
prefs['library_path'] = loc
self.callback(loc)
self.callback(loc, copy_structure=self.copy_structure.isChecked())
else:
move_library(self.db.library_path, loc, self.parent(),
self.callback)

View File

@ -49,11 +49,26 @@
</widget>
</item>
<item row="5" column="0" colspan="3">
<widget class="QRadioButton" name="empty_library">
<property name="text">
<string>&amp;Create an empty library at the new location</string>
</property>
</widget>
<layout class="QHBoxLayout" name="hbox1">
<item>
<widget class="QRadioButton" name="empty_library">
<property name="text">
<string>&amp;Create an empty library at the new location</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="copy_structure">
<property name="text">
<string>&amp;Copy structure from the current library</string>
</property>
<property name="toolTip">
<string>Copy the custom columns, saved searches, column widths, plugboards,
user categories, and other information from the old to the new library</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="6" column="0" colspan="3">
<widget class="QRadioButton" name="move_library">

View File

@ -23,7 +23,7 @@ from calibre.gui2.dialogs.tag_editor import TagEditor
from calibre.gui2.widgets import ProgressIndicator
from calibre.ebooks import BOOK_EXTENSIONS
from calibre.ebooks.metadata import string_to_authors, \
authors_to_string, check_isbn
authors_to_string, check_isbn, title_sort
from calibre.ebooks.metadata.covers import download_cover
from calibre.ebooks.metadata.meta import get_metadata
from calibre.ebooks.metadata import MetaInformation
@ -444,13 +444,24 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
self.cover_fetcher = None
self.bc_box.layout().setAlignment(self.cover, Qt.AlignCenter|Qt.AlignHCenter)
base = unicode(self.author_sort.toolTip())
self.ok_aus_tooltip = '<p>' + textwrap.fill(base+'<br><br>'+
ok_tooltip = '<p>' + textwrap.fill(base+'<br><br>'+
_(' The green color indicates that the current '
'author sort matches the current author'))
self.bad_aus_tooltip = '<p>'+textwrap.fill(base + '<br><br>'+
bad_tooltip = '<p>'+textwrap.fill(base + '<br><br>'+
_(' The red color indicates that the current '
'author sort does not match the current author'))
'author sort does not match the current author. '
'No action is required if this is what you want.'))
self.aus_tooltips = (ok_tooltip, bad_tooltip)
base = unicode(self.title_sort.toolTip())
ok_tooltip = '<p>' + textwrap.fill(base+'<br><br>'+
_(' The green color indicates that the current '
'title sort matches the current title'))
bad_tooltip = '<p>'+textwrap.fill(base + '<br><br>'+
_(' The red color warns that the current '
'title sort does not match the current title. '
'No action is required if this is what you want.'))
self.ts_tooltips = (ok_tooltip, bad_tooltip)
self.row_delta = 0
if prev:
self.prev_button = QPushButton(QIcon(I('back.png')), _('Previous'),
@ -506,7 +517,13 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
self.remove_unused_series)
QObject.connect(self.auto_author_sort, SIGNAL('clicked()'),
self.deduce_author_sort)
QObject.connect(self.auto_title_sort, SIGNAL('clicked()'),
self.deduce_title_sort)
self.trim_cover_button.clicked.connect(self.trim_cover)
self.connect(self.title_sort, SIGNAL('textChanged(const QString&)'),
self.title_sort_box_changed)
self.connect(self.title, SIGNAL('textChanged(const QString&)'),
self.title_box_changed)
self.connect(self.author_sort, SIGNAL('textChanged(const QString&)'),
self.author_sort_box_changed)
self.connect(self.authors, SIGNAL('editTextChanged(const QString&)'),
@ -523,6 +540,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
self.title.setText(db.title(row))
self.title_sort.setText(db.title_sort(row))
isbn = db.isbn(self.id, index_is_id=True)
if not isbn:
isbn = ''
@ -598,8 +616,8 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
w = self.central_widget.widget(1)
layout = w.layout()
self.custom_column_widgets, self.__cc_spacers = \
populate_metadata_page(layout, self.db, self.id,
parent=w, bulk=False, two_column=True)
populate_metadata_page(layout, self.db, self.id, parent=w, bulk=False,
two_column=tweaks['metadata_single_use_2_cols_for_custom_fields'])
self.__custom_col_layouts = [layout]
ans = self.custom_column_widgets
for i in range(len(ans)-1):
@ -610,27 +628,40 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
for c in range(2, len(ans[i].widgets), 2):
w.setTabOrder(ans[i].widgets[c-1], ans[i].widgets[c+1])
def title_box_changed(self, txt):
ts = unicode(txt)
ts = title_sort(ts)
self.mark_box_as_ok(control = self.title_sort, tt=self.ts_tooltips,
normal=(unicode(self.title_sort.text()) == ts))
def title_sort_box_changed(self, txt):
ts = unicode(txt)
self.mark_box_as_ok(control = self.title_sort, tt=self.ts_tooltips,
normal=(title_sort(unicode(self.title.text())) == ts))
def authors_box_changed(self, txt):
aus = unicode(txt)
aus = re.sub(r'\s+et al\.$', '', aus)
aus = self.db.author_sort_from_authors(string_to_authors(aus))
self.mark_author_sort(normal=(unicode(self.author_sort.text()) == aus))
self.mark_box_as_ok(control = self.author_sort, tt=self.aus_tooltips,
normal=(unicode(self.author_sort.text()) == aus))
def author_sort_box_changed(self, txt):
au = unicode(self.authors.text())
au = re.sub(r'\s+et al\.$', '', au)
au = self.db.author_sort_from_authors(string_to_authors(au))
self.mark_author_sort(normal=(au == txt))
self.mark_box_as_ok(control = self.author_sort, tt=self.aus_tooltips,
normal=(au == txt))
def mark_author_sort(self, normal=True):
def mark_box_as_ok(self, control, tt, normal=True):
if normal:
col = 'rgb(0, 255, 0, 20%)'
else:
col = 'rgb(255, 0, 0, 20%)'
self.author_sort.setStyleSheet('QLineEdit { color: black; '
'background-color: %s; }'%col)
tt = self.ok_aus_tooltip if normal else self.bad_aus_tooltip
self.author_sort.setToolTip(tt)
control.setStyleSheet('QLineEdit { color: black; '
'background-color: %s; }'%col)
tt = tt[0] if normal else tt[1]
control.setToolTip(tt)
def validate_isbn(self, isbn):
isbn = unicode(isbn).strip()
@ -652,12 +683,16 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
authors = string_to_authors(au)
self.author_sort.setText(self.db.author_sort_from_authors(authors))
def deduce_title_sort(self):
ts = unicode(self.title.text())
self.title_sort.setText(title_sort(ts))
def swap_title_author(self):
title = self.title.text()
self.title.setText(self.authors.text())
self.authors.setText(title)
self.author_sort.setText('')
self.deduce_author_sort()
self.deduce_title_sort()
def initialize_combos(self):
self.initalize_authors()
@ -804,7 +839,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
series = unicode(self.series.text()).strip()
if series and series != self.original_series_name:
ns = 1
if tweaks['series_index_auto_increment'] == 'next':
if tweaks['series_index_auto_increment'] != 'const':
ns = self.db.get_next_series_num_for(series)
self.series_index.setValue(ns)
self.original_series_name = series
@ -838,6 +873,10 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
title = unicode(self.title.text()).strip()
if title != self.original_title:
self.db.set_title(self.id, title, notify=False)
# This must be after setting the title because of the DB update trigger
ts = unicode(self.title_sort.text()).strip()
if ts:
self.db.set_title_sort(self.id, ts, notify=False, commit=False)
au = unicode(self.authors.text()).strip()
if au and au != self.original_author:
self.db.set_authors(self.id, string_to_authors(au), notify=False)

View File

@ -100,27 +100,27 @@
</property>
</widget>
</item>
<item row="0" column="2" rowspan="2">
<widget class="QToolButton" name="swap_button">
<property name="toolTip">
<string>Swap the author and title</string>
</property>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>...</string>
<string>Title &amp;sort: </string>
</property>
<property name="icon">
<iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/swap.png</normaloff>:/images/swap.png</iconset>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
<property name="buddy">
<cstring>title_sort</cstring>
</property>
</widget>
</item>
<item row="1" column="0">
<item row="1" column="1">
<widget class="EnLineEdit" name="title_sort">
<property name="toolTip">
<string>Specify how this book should be sorted when by title. For example, The Exorcist might be sorted as Exorcist, The.</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>&amp;Author(s): </string>
@ -133,7 +133,14 @@
</property>
</widget>
</item>
<item row="2" column="0">
<item row="2" column="1">
<widget class="EnComboBox" name="authors">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Author S&amp;ort: </string>
@ -146,34 +153,15 @@
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="EnLineEdit" name="author_sort">
<property name="toolTip">
<string>Specify how the author(s) of this book should be sorted. For example Charles Dickens should be sorted as Dickens, Charles.
<item row="3" column="1">
<widget class="EnLineEdit" name="author_sort">
<property name="toolTip">
<string>Specify how the author(s) of this book should be sorted. For example Charles Dickens should be sorted as Dickens, Charles.
If the box is colored green, then text matches the individual author's sort strings. If it is colored red, then the authors and this text do not match.</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="auto_author_sort">
<property name="toolTip">
<string>Automatically create the author sort entry based on the current author entry.
Using this button to create author sort will change author sort from red to green.</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/auto_author_sort.png</normaloff>:/images/auto_author_sort.png</iconset>
</property>
</widget>
</item>
</layout>
</property>
</widget>
</item>
<item row="3" column="0">
<item row="4" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>&amp;Rating:</string>
@ -186,7 +174,7 @@ Using this button to create author sort will change author sort from red to gree
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<item row="4" column="1" colspan="2">
<widget class="QSpinBox" name="rating">
<property name="toolTip">
<string>Rating of this book. 0-5 stars</string>
@ -205,7 +193,7 @@ Using this button to create author sort will change author sort from red to gree
</property>
</widget>
</item>
<item row="4" column="0">
<item row="5" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>&amp;Publisher: </string>
@ -218,7 +206,14 @@ Using this button to create author sort will change author sort from red to gree
</property>
</widget>
</item>
<item row="5" column="0">
<item row="5" column="1" colspan="2">
<widget class="EnComboBox" name="publisher">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Ta&amp;gs: </string>
@ -231,32 +226,7 @@ Using this button to create author sort will change author sort from red to gree
</property>
</widget>
</item>
<item row="5" column="1" colspan="2">
<layout class="QHBoxLayout" name="_2">
<item>
<widget class="TagsLineEdit" name="tags">
<property name="toolTip">
<string>Tags categorize the book. This is particularly useful while searching. &lt;br&gt;&lt;br&gt;They can be any words or phrases, separated by commas.</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="tag_editor_button">
<property name="toolTip">
<string>Open Tag Editor</string>
</property>
<property name="text">
<string>Open Tag Editor</string>
</property>
<property name="icon">
<iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/chapters.png</normaloff>:/images/chapters.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item row="6" column="0">
<item row="7" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>&amp;Series:</string>
@ -272,7 +242,7 @@ Using this button to create author sort will change author sort from red to gree
</property>
</widget>
</item>
<item row="6" column="1" colspan="2">
<item row="7" column="1">
<layout class="QHBoxLayout" name="_3">
<property name="spacing">
<number>5</number>
@ -293,59 +263,9 @@ Using this button to create author sort will change author sort from red to gree
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="remove_series_button">
<property name="toolTip">
<string>Remove unused series (Series that have no books)</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/trash.png</normaloff>:/images/trash.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>IS&amp;BN:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>isbn</cstring>
</property>
</widget>
</item>
<item row="8" column="1" colspan="2">
<widget class="QLineEdit" name="isbn"/>
</item>
<item row="10" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Publishe&amp;d:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>pubdate</cstring>
</property>
</widget>
</item>
<item row="4" column="1" colspan="2">
<widget class="EnComboBox" name="publisher">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="1" colspan="2">
<widget class="QDoubleSpinBox" name="series_index">
<property name="enabled">
<bool>false</bool>
@ -358,34 +278,23 @@ Using this button to create author sort will change author sort from red to gree
</property>
</widget>
</item>
<item row="10" column="1" colspan="2">
<widget class="QDateEdit" name="pubdate">
<property name="displayFormat">
<string>MMM yyyy</string>
<item row="9" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>IS&amp;BN:</string>
</property>
<property name="calendarPopup">
<bool>true</bool>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="EnComboBox" name="authors">
<property name="editable">
<bool>true</bool>
<property name="buddy">
<cstring>isbn</cstring>
</property>
</widget>
</item>
<item row="9" column="1" colspan="2">
<widget class="QDateEdit" name="date">
<property name="displayFormat">
<string>dd MMM yyyy</string>
</property>
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
<widget class="QLineEdit" name="isbn"/>
</item>
<item row="9" column="0">
<item row="10" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>&amp;Date:</string>
@ -398,9 +307,194 @@ Using this button to create author sort will change author sort from red to gree
</property>
</widget>
</item>
<item row="10" column="1" colspan="2">
<widget class="QDateEdit" name="date">
<property name="displayFormat">
<string>dd MMM yyyy</string>
</property>
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Publishe&amp;d:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>pubdate</cstring>
</property>
</widget>
</item>
<item row="11" column="1" colspan="2">
<widget class="QDateEdit" name="pubdate">
<property name="displayFormat">
<string>MMM yyyy</string>
</property>
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="2" rowspan="4">
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="auto_title_sort">
<property name="toolTip">
<string>Automatically create the title sort entry based on the current title entry.
Using this button to create title sort will change title sort from red to green.</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/auto_author_sort.png</normaloff>:/images/auto_author_sort.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="swap_button">
<property name="toolTip">
<string>Swap the author and title</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/swap.png</normaloff>:/images/swap.png</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="auto_author_sort">
<property name="toolTip">
<string>Automatically create the author sort entry based on the current author entry.
Using this button to create author sort will change author sort from red to green.</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/auto_author_sort.png</normaloff>:/images/auto_author_sort.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="6" column="1">
<layout class="QHBoxLayout" name="_2">
<item>
<widget class="TagsLineEdit" name="tags">
<property name="toolTip">
<string>Tags categorize the book. This is particularly useful while searching. &lt;br&gt;&lt;br&gt;They can be any words or phrases, separated by commas.</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="6" column="2">
<widget class="QToolButton" name="tag_editor_button">
<property name="toolTip">
<string>Open Tag Editor</string>
</property>
<property name="text">
<string>Open Tag Editor</string>
</property>
<property name="icon">
<iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/chapters.png</normaloff>:/images/chapters.png</iconset>
</property>
</widget>
</item>
<item row="7" column="2">
<widget class="QToolButton" name="remove_series_button">
<property name="toolTip">
<string>Remove unused series (Series that have no books)</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/trash.png</normaloff>:/images/trash.png</iconset>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QPushButton" name="fetch_metadata_button">
<property name="text">
<string>&amp;Fetch metadata from server</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
@ -420,13 +514,6 @@ Using this button to create author sort will change author sort from red to gree
</layout>
</widget>
</item>
<item>
<widget class="QPushButton" name="fetch_metadata_button">
<property name="text">
<string>&amp;Fetch metadata from server</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="layoutWidget_2">
@ -744,10 +831,12 @@ Using this button to create author sort will change author sort from red to gree
</customwidgets>
<tabstops>
<tabstop>title</tabstop>
<tabstop>auto_title_sort</tabstop>
<tabstop>title_sort</tabstop>
<tabstop>swap_button</tabstop>
<tabstop>authors</tabstop>
<tabstop>author_sort</tabstop>
<tabstop>auto_author_sort</tabstop>
<tabstop>author_sort</tabstop>
<tabstop>rating</tabstop>
<tabstop>publisher</tabstop>
<tabstop>tags</tabstop>
@ -758,20 +847,22 @@ Using this button to create author sort will change author sort from red to gree
<tabstop>isbn</tabstop>
<tabstop>date</tabstop>
<tabstop>pubdate</tabstop>
<tabstop>comments</tabstop>
<tabstop>fetch_metadata_button</tabstop>
<tabstop>add_format_button</tabstop>
<tabstop>remove_format_button</tabstop>
<tabstop>comments</tabstop>
<tabstop>button_set_cover</tabstop>
<tabstop>button_set_metadata</tabstop>
<tabstop>formats</tabstop>
<tabstop>add_format_button</tabstop>
<tabstop>remove_format_button</tabstop>
<tabstop>cover_path</tabstop>
<tabstop>cover_button</tabstop>
<tabstop>trim_cover_button</tabstop>
<tabstop>reset_cover</tabstop>
<tabstop>fetch_cover_button</tabstop>
<tabstop>generate_cover_button</tabstop>
<tabstop>button_box</tabstop>
<tabstop>scrollArea</tabstop>
<tabstop>central_widget</tabstop>
<tabstop>button_box</tabstop>
</tabstops>
<resources>
<include location="../../../../resources/images.qrc"/>

View File

@ -772,7 +772,7 @@ class BooksModel(QAbstractTableModel): # {{{
self.db.set_series_index(id, float(match.group(1)))
val = pat.sub('', val).strip()
elif val:
if tweaks['series_index_auto_increment'] == 'next':
if tweaks['series_index_auto_increment'] != 'const':
ni = self.db.get_next_series_num_for(val)
if ni != 1:
self.db.set_series_index(id, ni)

View File

@ -135,9 +135,10 @@ class GuiRunner(QObject):
'''Make sure an event loop is running before starting the main work of
initialization'''
def __init__(self, opts, args, actions, listener, app):
def __init__(self, opts, args, actions, listener, app, gui_debug=None):
self.startup_time = time.time()
self.opts, self.args, self.listener, self.app = opts, args, listener, app
self.gui_debug = gui_debug
self.actions = actions
self.main = None
QObject.__init__(self)
@ -148,7 +149,7 @@ class GuiRunner(QObject):
def start_gui(self):
from calibre.gui2.ui import Main
main = Main(self.opts)
main = Main(self.opts, gui_debug=self.gui_debug)
if self.splash_screen is not None:
self.splash_screen.showMessage(_('Initializing user interface...'))
self.splash_screen.finish(main)
@ -249,34 +250,69 @@ class GuiRunner(QObject):
self.initialize_db()
def run_in_debug_mode(logpath=None):
e = sys.executable if getattr(sys, 'frozen', False) else sys.argv[0]
import tempfile, subprocess
fd, logpath = tempfile.mkstemp('.txt')
os.close(fd)
if hasattr(sys, 'frameworks_dir'):
base = os.path.dirname(sys.frameworks_dir)
if 'console.app' not in base:
base = os.path.join(base, 'console.app', 'Contents')
exe = os.path.basename(e)
exe = os.path.join(base, 'MacOS', exe+'-debug')
else:
base, ext = os.path.splitext(e)
exe = base + '-debug' + ext
print 'Starting debug executable:', exe
creationflags = 0
if iswindows:
import win32process
creationflags = win32process.CREATE_NO_WINDOW
subprocess.Popen([exe, '--gui-debug', logpath], stdout=open(logpath, 'w'),
stderr=subprocess.STDOUT, stdin=open(os.devnull, 'r'),
creationflags=creationflags)
def run_gui(opts, args, actions, listener, app):
def run_gui(opts, args, actions, listener, app, gui_debug=None):
initialize_file_icon_provider()
if not dynamic.get('welcome_wizard_was_run', False):
from calibre.gui2.wizard import wizard
wizard().exec_()
dynamic.set('welcome_wizard_was_run', True)
runner = GuiRunner(opts, args, actions, listener, app)
runner = GuiRunner(opts, args, actions, listener, app, gui_debug=gui_debug)
ret = app.exec_()
if getattr(runner.main, 'run_wizard_b4_shutdown', False):
from calibre.gui2.wizard import wizard
wizard().exec_()
if getattr(runner.main, 'restart_after_quit', False):
e = sys.executable if getattr(sys, 'frozen', False) else sys.argv[0]
print 'Restarting with:', e, sys.argv
if hasattr(sys, 'frameworks_dir'):
app = os.path.dirname(os.path.dirname(sys.frameworks_dir))
import subprocess
subprocess.Popen('sleep 3s; open '+app, shell=True)
if getattr(runner.main, 'debug_on_restart', False):
run_in_debug_mode()
else:
os.execvp(e, sys.argv)
print 'Restarting with:', e, sys.argv
if hasattr(sys, 'frameworks_dir'):
app = os.path.dirname(os.path.dirname(sys.frameworks_dir))
import subprocess
subprocess.Popen('sleep 3s; open '+app, shell=True)
else:
os.execvp(e, sys.argv)
else:
if iswindows:
try:
runner.main.system_tray_icon.hide()
except:
pass
if runner.main.gui_debug is not None:
e = sys.executable if getattr(sys, 'frozen', False) else sys.argv[0]
import subprocess
creationflags = 0
if iswindows:
import win32process
creationflags = win32process.CREATE_NO_WINDOW
subprocess.Popen([e, '--show-gui-debug', runner.main.gui_debug],
creationflags=creationflags, stdout=open(os.devnull, 'w'),
stderr=subprocess.PIPE, stdin=open(os.devnull, 'r'))
return ret
def cant_start(msg=_('If you are sure it is not running')+', ',
@ -317,6 +353,11 @@ def communicate(args):
def main(args=sys.argv):
gui_debug = None
if args[0] == '__CALIBRE_GUI_DEBUG__':
gui_debug = args[1]
args = ['calibre']
app, opts, args, actions = init_qt(args)
from calibre.utils.lock import singleinstance
from multiprocessing.connection import Listener
@ -333,9 +374,11 @@ def main(args=sys.argv):
except socket.error:
cant_start()
else:
return run_gui(opts, args, actions, listener, app)
return run_gui(opts, args, actions, listener, app,
gui_debug=gui_debug)
else:
return run_gui(opts, args, actions, listener, app)
return run_gui(opts, args, actions, listener, app,
gui_debug=gui_debug)
otherinstance = False
try:
listener = Listener(address=ADDRESS)
@ -345,8 +388,7 @@ def main(args=sys.argv):
# On windows only singleinstance can be trusted
otherinstance = True if iswindows else False
if not otherinstance:
sys.setcheckinterval(50) # Make GUI more responsive
return run_gui(opts, args, actions, listener, app)
return run_gui(opts, args, actions, listener, app, gui_debug=gui_debug)
communicate(args)

View File

@ -96,10 +96,11 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
'The main GUI'
def __init__(self, opts, parent=None):
def __init__(self, opts, parent=None, gui_debug=None):
MainWindow.__init__(self, opts, parent)
self.opts = opts
self.device_connected = None
self.gui_debug = gui_debug
acmap = OrderedDict()
for action in interface_actions():
ac = action.load_actual_plugin(self)
@ -261,6 +262,14 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
for ac in self.iactions.values():
ac.initialization_complete()
if show_gui and self.gui_debug is not None:
info_dialog(self, _('Debug mode'), '<p>' +
_('You have started calibre in debug mode. After you '
'quit calibre, the debug log will be available in '
'the file: %s<p>The '
'log will be displayed automatically.')%self.gui_debug, show=True)
def start_content_server(self):
from calibre.library.server.main import start_threaded_server
from calibre.library.server import server_config
@ -369,13 +378,16 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
def booklists(self):
return self.memory_view.model().db, self.card_a_view.model().db, self.card_b_view.model().db
def library_moved(self, newloc):
def library_moved(self, newloc, copy_structure=False):
if newloc is None: return
default_prefs = None
try:
olddb = self.library_view.model().db
if copy_structure:
default_prefs = olddb.prefs
except:
olddb = None
db = LibraryDatabase2(newloc)
db = LibraryDatabase2(newloc, default_prefs=default_prefs)
if self.content_server is not None:
self.content_server.set_database(db)
self.library_path = newloc
@ -495,7 +507,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
dynamic.set('sort_history', self.library_view.model().sort_history)
self.save_layout_state()
def quit(self, checked=True, restart=False):
def quit(self, checked=True, restart=False, debug_on_restart=False):
if not self.confirm_quit():
return
try:
@ -503,6 +515,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
except:
pass
self.restart_after_quit = restart
self.debug_on_restart = debug_on_restart
QApplication.instance().quit()
def donate(self, *args):

View File

@ -707,7 +707,7 @@ def parse_series_string(db, label, value):
val = pat.sub('', val).strip()
s_index = float(match.group(1))
elif val:
if tweaks['series_index_auto_increment'] == 'next':
if tweaks['series_index_auto_increment'] != 'const':
s_index = db.get_next_cc_series_num_for(val, label=label)
else:
s_index = 1.0

View File

@ -8,12 +8,12 @@ __docformat__ = 'restructuredtext en'
import json, re
from functools import partial
from math import floor
from calibre import prints
from calibre.constants import preferred_encoding
from calibre.library.field_metadata import FieldMetadata
from calibre.utils.date import parse_date
from calibre.utils.config import tweaks
class CustomColumns(object):
@ -261,15 +261,15 @@ class CustomColumns(object):
series_id = self.conn.get('SELECT id from %s WHERE value=?'%table,
(series,), all=False)
if series_id is None:
if isinstance(tweaks['series_index_auto_increment'], (int, float)):
return float(tweaks['series_index_auto_increment'])
return 1.0
# get the label of the associated series number table
series_num = self.conn.get('''
SELECT MAX({lt}.extra) FROM {lt}
series_indices = self.conn.get('''
SELECT {lt}.extra FROM {lt}
WHERE {lt}.book IN (SELECT book FROM {lt} where value=?)
'''.format(lt=lt), (series_id,), all=False)
if series_num is None:
return 1.0
return floor(series_num+1)
ORDER BY {lt}.extra
'''.format(lt=lt), (series_id,))
return self._get_next_series_num_for_list(series_indices)
def all_custom(self, label=None, num=None):
if label is not None:

View File

@ -8,7 +8,7 @@ The database used to store ebook metadata
'''
import os, sys, shutil, cStringIO, glob, time, functools, traceback, re
from itertools import repeat
from math import floor
from math import ceil
from Queue import Queue
from PyQt4.QtGui import QImage
@ -113,7 +113,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
def exists_at(cls, path):
return path and os.path.exists(os.path.join(path, 'metadata.db'))
def __init__(self, library_path, row_factory=False):
def __init__(self, library_path, row_factory=False, default_prefs=None):
self.field_metadata = FieldMetadata()
self.dirtied_queue = Queue()
if not os.path.exists(library_path):
@ -127,10 +127,29 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
if isinstance(self.dbpath, unicode) and not iswindows:
self.dbpath = self.dbpath.encode(filesystem_encoding)
apply_default_prefs = not os.path.exists(self.dbpath)
self.connect()
self.is_case_sensitive = not iswindows and not isosx and \
not os.path.exists(self.dbpath.replace('metadata.db', 'MeTAdAtA.dB'))
SchemaUpgrade.__init__(self)
# if we are to copy the prefs and structure from some other DB, then
# we need to do it before we call initialize_dynamic
if apply_default_prefs and default_prefs is not None:
dbprefs = DBPrefs(self)
for key in default_prefs:
# be sure that prefs not to be copied are listed below
if key in ['news_to_be_synced']:
continue
try:
dbprefs[key] = default_prefs[key]
except:
pass # ignore options that don't exist anymore
fmvals = [f for f in default_prefs['field_metadata'].values() if f['is_custom']]
for f in fmvals:
self.create_custom_column(f['label'], f['name'], f['datatype'],
f['is_multiple'] is not None, f['is_editable'], f['display'])
self.initialize_dynamic()
def get_property(self, idx, index_is_id=False, loc=-1):
@ -1365,14 +1384,42 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
series_id = self.conn.get('SELECT id from series WHERE name=?',
(series,), all=False)
if series_id is None:
if isinstance(tweaks['series_index_auto_increment'], (int, float)):
return float(tweaks['series_index_auto_increment'])
return 1.0
series_num = self.conn.get(
('SELECT MAX(series_index) FROM books WHERE id IN '
'(SELECT book FROM books_series_link where series=?)'),
(series_id,), all=False)
if series_num is None:
series_indices = self.conn.get(
('SELECT series_index FROM books WHERE id IN '
'(SELECT book FROM books_series_link where series=?) '
'ORDER BY series_index'),
(series_id,))
return self._get_next_series_num_for_list(series_indices)
def _get_next_series_num_for_list(self, series_indices):
if not series_indices:
if isinstance(tweaks['series_index_auto_increment'], (int, float)):
return float(tweaks['series_index_auto_increment'])
return 1.0
return floor(series_num+1)
series_indices = [x[0] for x in series_indices]
if tweaks['series_index_auto_increment'] == 'next':
return series_indices[-1] + 1
if tweaks['series_index_auto_increment'] == 'first_free':
for i in range(1, 10000):
if i not in series_indices:
return i
# really shouldn't get here.
if tweaks['series_index_auto_increment'] == 'next_free':
for i in range(int(ceil(series_indices[0])), 10000):
if i not in series_indices:
return i
# really shouldn't get here.
if tweaks['series_index_auto_increment'] == 'last_free':
for i in range(int(ceil(series_indices[-1])), 0, -1):
if i not in series_indices:
return i
return series_indices[-1] + 1
if isinstance(tweaks['series_index_auto_increment'], (int, float)):
return float(tweaks['series_index_auto_increment'])
return 1.0
def set(self, row, column, val):
'''
@ -1565,6 +1612,20 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
if notify:
self.notify('metadata', [id])
def set_title_sort(self, id, title_sort_, notify=True, commit=True):
if not title_sort_:
return False
if isbytestring(title_sort_):
title_sort_ = title_sort_.decode(preferred_encoding, 'replace')
self.conn.execute('UPDATE books SET sort=? WHERE id=?', (title_sort_, id))
self.data.set(id, self.FIELD_MAP['sort'], title_sort_, row_is_id=True)
self.dirtied([id], commit=False)
if commit:
self.conn.commit()
if notify:
self.notify('metadata', [id])
return True
def _set_title(self, id, title):
if not title:
return False
@ -1746,18 +1807,17 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
FROM books, books_series_link as lt
WHERE books.id = lt.book AND lt.series=?
ORDER BY books.series_index''', (old_id,))
# Get the next series index
index = self.get_next_series_num_for(new_name)
# Now update the link table
self.conn.execute('''UPDATE books_series_link
SET series=?
WHERE series=?''',(new_id, old_id,))
# Now set the indices
for (book_id,) in books:
# Get the next series index
index = self.get_next_series_num_for(new_name)
self.conn.execute('''UPDATE books
SET series_index=?
WHERE id=?''',(index, book_id,))
index = index + 1
self.dirty_books_referencing('series', new_id, commit=False)
self.conn.commit()

View File

@ -429,3 +429,13 @@ class SchemaUpgrade(object):
'Remove commas from tags'
self.conn.execute("UPDATE tags SET name=REPLACE(name, ',', ';')")
def upgrade_version_16(self):
self.conn.executescript('''
DROP TRIGGER IF EXISTS books_update_trg;
CREATE TRIGGER books_update_trg
AFTER UPDATE ON books
BEGIN
UPDATE books SET sort=title_sort(NEW.title)
WHERE id=NEW.id AND OLD.title <> NEW.title;
END;
''')

View File

@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: calibre\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2010-12-10 22:25+0000\n"
"PO-Revision-Date: 2010-12-14 19:28+0000\n"
"Last-Translator: Kenan Dervišević <Unknown>\n"
"PO-Revision-Date: 2010-12-16 22:50+0000\n"
"Last-Translator: Kovid Goyal <Unknown>\n"
"Language-Team: Bosnian <bs@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-12-15 04:35+0000\n"
"X-Launchpad-Export-Date: 2010-12-17 04:42+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:43

View File

@ -11,13 +11,13 @@ msgstr ""
"Project-Id-Version: ca\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-12-10 22:25+0000\n"
"PO-Revision-Date: 2010-12-13 17:37+0000\n"
"PO-Revision-Date: 2010-12-16 23:54+0000\n"
"Last-Translator: FerranRius <frius64@hotmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-12-14 04:50+0000\n"
"X-Launchpad-Export-Date: 2010-12-17 04:42+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:43

File diff suppressed because it is too large Load Diff

View File

@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: calibre\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2010-12-10 22:25+0000\n"
"PO-Revision-Date: 2010-12-11 22:59+0000\n"
"Last-Translator: Glenn <Unknown>\n"
"PO-Revision-Date: 2010-12-17 00:31+0000\n"
"Last-Translator: Kovid Goyal <Unknown>\n"
"Language-Team: Danish <da@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-12-13 04:57+0000\n"
"X-Launchpad-Export-Date: 2010-12-17 04:42+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:43

View File

@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: de\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-12-10 22:25+0000\n"
"PO-Revision-Date: 2010-12-11 02:44+0000\n"
"Last-Translator: Kovid Goyal <Unknown>\n"
"PO-Revision-Date: 2010-12-16 12:49+0000\n"
"Last-Translator: Manichean <Unknown>\n"
"Language-Team: American English <kde-i18n-doc@lists.kde.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-12-12 04:35+0000\n"
"X-Launchpad-Export-Date: 2010-12-17 04:43+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"Generated-By: pygettext.py 1.5\n"
@ -2470,23 +2470,23 @@ msgstr "Comic"
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/amazonfr.py:26
msgid "Downloads metadata from amazon.fr"
msgstr ""
msgstr "Herunterladen der Metadaten von amazon.fr"
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/amazonfr.py:43
msgid "Downloads metadata from amazon.com in spanish"
msgstr ""
msgstr "Herunterladen der spanischen Metadaten von amazon.com"
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/amazonfr.py:60
msgid "Downloads metadata from amazon.com in english"
msgstr ""
msgstr "Herunterladen der englischen Metadaten von amazon.com"
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/amazonfr.py:77
msgid "Downloads metadata from amazon.de"
msgstr ""
msgstr "Herunterladen der Metadaten von amazon.de"
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/amazonfr.py:94
msgid "Downloads metadata from amazon.com"
msgstr ""
msgstr "Herunterladen der Metadaten von amazon.com"
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/amazonfr.py:474
msgid ""
@ -2500,6 +2500,14 @@ msgid ""
" All & english & french & german & spanish\n"
" "
msgstr ""
" %prog [Optionen]\n"
"\n"
" Lädt Metadaten von Amazon. Sie müssen einen Titel, Author,\n"
" ISBN, Herausgeber oder Stichwort angeben. Es werden maximal\n"
" 10 Treffer geladen, suchen Sie so spezifisch wie möglich.\n"
" Sie können die Sprache für die Metadaten auswählen:\n"
" Alle & Englisch & Französisch & Deutsch & Spanisch\n"
" "
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/archive.py:41
msgid ""
@ -2832,33 +2840,35 @@ msgstr "Lädt Reihe/Etiketten/Bewertung von librarything.com"
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:25
msgid "Downloads metadata from Fictionwise"
msgstr ""
msgstr "Herunterladen der Metadaten von Fictionwise"
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:90
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:108
msgid "Query: %s"
msgstr ""
msgstr "Abfrage: %s"
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:100
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:285
msgid "Fictionwise timed out. Try again later."
msgstr ""
msgstr "Timeout bei Fictionwise. Bitte später nochmal versuchen."
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:101
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:286
msgid "Fictionwise encountered an error."
msgstr ""
msgstr "Bei Fictionwise ist ein Fehler aufgetreten."
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:219
msgid ""
"SUMMARY:\n"
" %s"
msgstr ""
"INHALTSANGABE:\n"
" %s"
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:316
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:333
msgid "Failed to get all details for an entry"
msgstr ""
msgstr "Konnte für einen Eintrag nicht alle Details holen"
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:354
msgid ""
@ -2871,41 +2881,49 @@ msgid ""
" so you should make your query as specific as possible.\n"
" "
msgstr ""
" %prog [Optionen]\n"
"\n"
" Holt Metadaten von Fictionwise. Sie müssen einen Titel, Autor oder "
"Stichwort\n"
" angeben. Angabe einer ISBN ist nicht möglich. Maximal werden 20 "
"Treffer geholt,\n"
" suchen Sie also möglichst spezifisch.\n"
" "
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:362
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:363
msgid "Book title"
msgstr ""
msgstr "Titel"
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:363
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:364
msgid "Book author(s)"
msgstr ""
msgstr "Autor(en)"
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:364
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:365
msgid "Book publisher"
msgstr ""
msgstr "Herausgeber"
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:365
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:367
msgid "Keywords"
msgstr ""
msgstr "Schlüsselworte"
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:367
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:373
msgid "Maximum number of results to fetch"
msgstr ""
msgstr "Maximale Anzahl an zu holenden Ergebnissen"
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:369
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:375
msgid "Be more verbose about errors"
msgstr ""
msgstr "Fehler ausführlicher berichten"
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fictionwise.py:383
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:390
msgid "No result found for this search!"
msgstr ""
msgstr "Keine Ergebnisse für diese Suche gefunden!"
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:107
msgid ""
@ -2983,11 +3001,11 @@ msgstr "Timeout von Nicebooks. Bitte versuchen Sie es später nochmal."
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:119
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:243
msgid "Nicebooks encountered an error."
msgstr ""
msgstr "Bei Nicebooks ist ein Fehler aufgetreten."
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:323
msgid "ISBN: %s not found."
msgstr ""
msgstr "ISBN: %s nicht gefunden."
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:324
msgid "An errror occured with Nicebooks cover fetcher"
@ -3007,7 +3025,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:366
msgid "Book ISBN"
msgstr ""
msgstr "ISBN"
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/nicebooks.py:369
msgid "Covers: 1-Check/ 2-Download"

View File

@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: calibre\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2010-12-10 22:25+0000\n"
"PO-Revision-Date: 2010-12-12 17:20+0000\n"
"Last-Translator: Vladimir Oka <Unknown>\n"
"PO-Revision-Date: 2010-12-16 23:27+0000\n"
"Last-Translator: Kovid Goyal <Unknown>\n"
"Language-Team: English (United Kingdom) <en_GB@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-12-13 04:58+0000\n"
"X-Launchpad-Export-Date: 2010-12-17 04:45+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:43

View File

@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: calibre\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2010-12-10 22:25+0000\n"
"PO-Revision-Date: 2010-12-15 17:49+0000\n"
"PO-Revision-Date: 2010-12-16 23:28+0000\n"
"Last-Translator: gorkaazk <gorkaazkarate@euskalerria.org>\n"
"Language-Team: Basque <eu@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-12-16 04:32+0000\n"
"X-Launchpad-Export-Date: 2010-12-17 04:42+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:43

View File

@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: calibre 0.4.22\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-12-10 22:25+0000\n"
"PO-Revision-Date: 2010-12-16 02:50+0000\n"
"Last-Translator: sengian <Unknown>\n"
"PO-Revision-Date: 2010-12-16 23:44+0000\n"
"Last-Translator: Kovid Goyal <Unknown>\n"
"Language-Team: Français <kde-i18n-doc@kde.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-12-16 04:33+0000\n"
"X-Launchpad-Export-Date: 2010-12-17 04:43+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Bookmarks: 1177,1104,-1,-1,-1,-1,-1,-1,-1,-1\n"
"Generated-By: pygettext.py 1.5\n"

View File

@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: calibre\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2010-12-10 22:25+0000\n"
"PO-Revision-Date: 2010-12-15 12:01+0000\n"
"PO-Revision-Date: 2010-12-17 00:16+0000\n"
"Last-Translator: Miguel Anxo Bouzada <mbouzada@gmail.com>\n"
"Language-Team: dev@gl.openoffice.org\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-12-16 04:33+0000\n"
"X-Launchpad-Export-Date: 2010-12-17 04:43+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"Language: gl\n"
@ -406,8 +406,8 @@ msgid ""
"Setup sharing of books via email. Can be used for automatic sending of "
"downloaded news to your devices"
msgstr ""
"Configura a compartición de libros por correo electrónico. Pódese usar para "
"enviar automaticamente as noticias descargadas aos seus dispositivos"
"Configura a compartición de libros por correo. Pódese usar para enviar "
"automaticamente as noticias descargadas aos seus dispositivos"
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:855
msgid "Sharing over the net"
@ -8751,7 +8751,7 @@ msgstr "Código fonte das receitas (pytom)"
#: /home/kovid/work/calibre/src/calibre/gui2/email.py:145
msgid "Email %s to %s"
msgstr "Enviar por correo electrónico %s a %s"
msgstr "Enviar por correo %s a %s"
#: /home/kovid/work/calibre/src/calibre/gui2/email.py:187
msgid "News:"
@ -9932,13 +9932,13 @@ msgid ""
"automatically sent for downloaded news to all email addresses that have Auto-"
"send checked."
msgstr ""
"O Calibre pode enviarlle os libros por correo-e. Enviaránselle correos "
"O Calibre pode enviarlle os libros por correo. Enviaránselle correos "
"automaticamente coas novas descargadas que teñen marcada a opción Enviar "
"automaticamente."
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/email_ui.py:67
msgid "Add an email address to which to send books"
msgstr "Engadir un enderezo de correo electrónico ao que enviar os libros"
msgstr "Engadir un enderezo de correo ao que enviar os libros"
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/email_ui.py:68
msgid "&Add email"
@ -9958,7 +9958,7 @@ msgstr "Enviar automaticamente"
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/emailp.py:24
msgid "Email"
msgstr "Correo electrónico"
msgstr "Correo"
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/emailp.py:29
msgid "Formats to email. The first matching format will be sent."
@ -11668,15 +11668,14 @@ msgid ""
"button below. You will also have to register your gmail address in your "
"Amazon account."
msgstr ""
"<p>Calibre pode enviar libros automaticamente por correo electrónico ao seu "
"Kindle. Debe configurar o envío por correo electrónico. A forma más doada e "
"facerse cunha <a href=\"http://gmail.com\">conta gratuíta de Gmail</a> e "
"premer o botón Usar gmail. Tamén deberá rexistrar o enderezo de gmail na súa "
"conta de Amazon."
"<p>Calibre pode enviar libros automaticamente por correo ao seu Kindle. Debe "
"configurar o envío por correo. A forma más doada e facerse cunha <a "
"href=\"http://gmail.com\">conta gratuíta de Gmail</a> e premer o botón Usar "
"gmail. Tamén deberá rexistrar o enderezo de gmail na súa conta de Amazon."
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/kindle_ui.py:50
msgid "&Kindle email:"
msgstr "Correo electrónico do &Kindle:"
msgstr "Correo do &Kindle:"
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/library_ui.py:57
msgid "Choose your &language:"
@ -11765,7 +11764,7 @@ msgstr "Configuración errada"
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/send_email.py:197
msgid "You must set the From email address"
msgstr "Debe estabelecer o enderezo de correo-e remitente"
msgstr "Debe estabelecer o enderezo de correo remitente"
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/send_email.py:204
msgid "You must set the username and password for the mail server."
@ -11781,8 +11780,8 @@ msgid ""
"<p>This is what will be present in the From: field of emails sent by "
"calibre.<br> Set it to your email address"
msgstr ""
"<p>Isto é o que se mostrará no campo De: dos correos electrónicos enviados "
"por Calibre.<br>Poña o seu enderezo de correo-e."
"<p>Isto é o que se mostrará no campo De: dos correos enviados por "
"Calibre.<br>Poña o seu enderezo de correo."
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/send_email_ui.py:126
msgid ""

View File

@ -9,13 +9,13 @@ msgstr ""
"Project-Id-Version: calibre_calibre-it\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-12-10 22:25+0000\n"
"PO-Revision-Date: 2010-12-12 08:58+0000\n"
"Last-Translator: MeltingShell <Unknown>\n"
"PO-Revision-Date: 2010-12-16 23:08+0000\n"
"Last-Translator: Kovid Goyal <Unknown>\n"
"Language-Team: italiano\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-12-13 04:57+0000\n"
"X-Launchpad-Export-Date: 2010-12-17 04:43+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Bookmarks: -1,-1,-1,-1,-1,1105,-1,1312,-1,-1\n"
"Generated-By: pygettext.py 1.5\n"

View File

@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: calibre\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2010-12-10 22:25+0000\n"
"PO-Revision-Date: 2010-12-12 12:28+0000\n"
"PO-Revision-Date: 2010-12-16 23:11+0000\n"
"Last-Translator: Hiroshi Miura <miurahr@linux.com>\n"
"Language-Team: Japanese <ja@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-12-13 04:58+0000\n"
"X-Launchpad-Export-Date: 2010-12-17 04:44+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:43

View File

@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: calibre\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2010-12-10 22:25+0000\n"
"PO-Revision-Date: 2010-12-11 02:28+0000\n"
"Last-Translator: Namsik Chu <Unknown>\n"
"PO-Revision-Date: 2010-12-17 01:06+0000\n"
"Last-Translator: Kovid Goyal <Unknown>\n"
"Language-Team: Korean <ko@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-12-12 04:37+0000\n"
"X-Launchpad-Export-Date: 2010-12-17 04:44+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:43

View File

@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: calibre\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2010-12-10 22:25+0000\n"
"PO-Revision-Date: 2010-12-16 03:36+0000\n"
"Last-Translator: geordee <Unknown>\n"
"PO-Revision-Date: 2010-12-16 23:06+0000\n"
"Last-Translator: Kovid Goyal <Unknown>\n"
"Language-Team: Malayalam <ml@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-12-16 04:33+0000\n"
"X-Launchpad-Export-Date: 2010-12-17 04:44+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:43

View File

@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: calibre\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2010-12-10 22:25+0000\n"
"PO-Revision-Date: 2010-12-05 04:33+0000\n"
"Last-Translator: Wespa Digital <Unknown>\n"
"PO-Revision-Date: 2010-12-16 16:26+0000\n"
"Last-Translator: marco cunha <Unknown>\n"
"Language-Team: American English <kde-i18n-doc@kde.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-12-11 04:44+0000\n"
"X-Launchpad-Export-Date: 2010-12-17 04:45+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:43
@ -387,7 +387,7 @@ msgstr "Configuração dos Metadados"
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:838
msgid "Change metadata fields before saving/sending"
msgstr ""
msgstr "Alterar campos de metadados antes de salvar / enviar"
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:843
msgid "Sharing books by email"
@ -582,6 +582,7 @@ msgstr "Destinado ao iPad e dispositivos similares com resolução de 768x1024"
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:437
msgid "Intended for generic tablet devices, does no resizing of images"
msgstr ""
"Pretendido para dispositivos Tablets, não faz o redimensionamento de imagens"
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:464
msgid "This profile is intended for the Kobo Reader."
@ -609,11 +610,11 @@ msgstr "Este perfil é destinado para o Kindle DX da Amazon."
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:686
msgid "This profile is intended for the B&N Nook Color."
msgstr ""
msgstr "Este perfil é destinado para a B & N Nook Color."
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:697
msgid "This profile is intended for the Sanda Bambook."
msgstr ""
msgstr "Este perfil é destinado para o Sanda Bambook"
#: /home/kovid/work/calibre/src/calibre/customize/ui.py:34
msgid "Installed plugins"
@ -719,6 +720,9 @@ msgid ""
"Cannot copy books directly from iDevice. Drag from iTunes Library to "
"desktop, then add to calibre's Library window."
msgstr ""
"Não é possível copiar livros diretamente do iDevice. Arraste a partir do "
"iTunes Library para o desktop, em seguida, adicione para a biblioteca "
"calibre."
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:260
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:263
@ -812,7 +816,7 @@ msgstr "Comunica-se com o leitor Cybook Gen 3 / Opus."
#: /home/kovid/work/calibre/src/calibre/devices/cybook/driver.py:64
msgid "Communicate with the Cybook Orizon eBook reader."
msgstr ""
msgstr "Comunique-se com o leitor eBook Cybook Orizon."
#: /home/kovid/work/calibre/src/calibre/devices/eb600/driver.py:24
msgid "Communicate with the EB600 eBook reader."
@ -828,7 +832,7 @@ msgstr "Comunica-se com o leitor PocketBook 301"
#: /home/kovid/work/calibre/src/calibre/devices/eb600/driver.py:233
msgid "Communicate with the PocketBook 602 reader."
msgstr ""
msgstr "Comunique-se com o leitor PocketBook 602."
#: /home/kovid/work/calibre/src/calibre/devices/edge/driver.py:17
msgid "Entourage Edge"
@ -917,7 +921,7 @@ msgstr "John Schember"
#: /home/kovid/work/calibre/src/calibre/devices/interface.py:44
msgid "Cannot get files from this device"
msgstr ""
msgstr "Não é possível obter arquivos a partir deste dispositivo"
#: /home/kovid/work/calibre/src/calibre/devices/irexdr/driver.py:16
msgid "Communicate with the IRex Digital Reader 1000 eBook reader."
@ -941,7 +945,7 @@ msgstr "Comunicar com o leitor MiBuk Wolder."
#: /home/kovid/work/calibre/src/calibre/devices/jetbook/driver.py:116
msgid "Communicate with the JetBook Mini reader."
msgstr ""
msgstr "Comunique-se com o leitor Mini jetBook."
#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:43
msgid "Communicate with the Kindle eBook reader."

View File

@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: calibre\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2010-12-10 22:25+0000\n"
"PO-Revision-Date: 2010-12-12 15:48+0000\n"
"Last-Translator: Mircea Dochia <Unknown>\n"
"PO-Revision-Date: 2010-12-17 00:09+0000\n"
"Last-Translator: Kovid Goyal <Unknown>\n"
"Language-Team: Romanian <ro@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-12-13 04:58+0000\n"
"X-Launchpad-Export-Date: 2010-12-17 04:44+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:43

View File

@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: calibre 0.4.55\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-12-10 22:25+0000\n"
"PO-Revision-Date: 2010-12-14 16:19+0000\n"
"Last-Translator: Konstantin <Unknown>\n"
"PO-Revision-Date: 2010-12-16 22:56+0000\n"
"Last-Translator: Kovid Goyal <Unknown>\n"
"Language-Team: American English <kde-i18n-doc@lists.kde.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-12-15 04:36+0000\n"
"X-Launchpad-Export-Date: 2010-12-17 04:44+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: RUSSIAN FEDERATION\n"
"X-Poedit-Language: Russian\n"

View File

@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: calibre 0.4.17\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-12-10 22:25+0000\n"
"PO-Revision-Date: 2010-12-14 10:17+0000\n"
"Last-Translator: Stane Accetto <Unknown>\n"
"PO-Revision-Date: 2010-12-16 22:54+0000\n"
"Last-Translator: Kovid Goyal <Unknown>\n"
"Language-Team: sl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-12-15 04:37+0000\n"
"X-Launchpad-Export-Date: 2010-12-17 04:45+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"Generated-By: pygettext.py 1.5\n"

View File

@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: calibre\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2010-12-10 22:25+0000\n"
"PO-Revision-Date: 2010-12-13 11:44+0000\n"
"Last-Translator: Vladimir Oka <Unknown>\n"
"PO-Revision-Date: 2010-12-16 23:13+0000\n"
"Last-Translator: Kovid Goyal <Unknown>\n"
"Language-Team: Serbian <sr@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-12-14 04:51+0000\n"
"X-Launchpad-Export-Date: 2010-12-17 04:45+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:43