mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Merge from virt lib
This commit is contained in:
commit
418c24138c
@ -28,7 +28,7 @@
|
|||||||
description: "To enable them go to Preferences->Metadata download and enable the 'Google Image' and 'Big Book Search' sources. Google Images is useful for finding larger covers as well as alternate versions of the cover. Big Book Search searches for alternate covers from amazon.com. It can occasionally find nicer covers than the direct Amazon source. Note that both these sources download multiple covers for a single book. Some of these covers can be wrong (i.e. they may be of a different book or not covers at all, so you should inspect the results and manually pick the best match). When bulk downloading, these sources are only used if the other sources find no covers."
|
description: "To enable them go to Preferences->Metadata download and enable the 'Google Image' and 'Big Book Search' sources. Google Images is useful for finding larger covers as well as alternate versions of the cover. Big Book Search searches for alternate covers from amazon.com. It can occasionally find nicer covers than the direct Amazon source. Note that both these sources download multiple covers for a single book. Some of these covers can be wrong (i.e. they may be of a different book or not covers at all, so you should inspect the results and manually pick the best match). When bulk downloading, these sources are only used if the other sources find no covers."
|
||||||
type: major
|
type: major
|
||||||
|
|
||||||
- title: "Content server: Allow specifying a reestriction to use for the server when embedding it as a WSGI app."
|
- title: "Content server: Allow specifying a restriction to use for the server when embedding it as a WSGI app."
|
||||||
tickets: [1167951]
|
tickets: [1167951]
|
||||||
|
|
||||||
- title: "Get Books: Add a plugin for the Koobe Polish book store"
|
- title: "Get Books: Add a plugin for the Koobe Polish book store"
|
||||||
|
@ -10,8 +10,7 @@ from functools import partial
|
|||||||
from threading import Thread
|
from threading import Thread
|
||||||
from contextlib import closing
|
from contextlib import closing
|
||||||
|
|
||||||
from PyQt4.Qt import (QToolButton, QDialog, QGridLayout, QIcon, QLabel,
|
from PyQt4.Qt import (QToolButton, QDialog, QGridLayout, QIcon, QLabel, QDialogButtonBox)
|
||||||
QCheckBox, QDialogButtonBox)
|
|
||||||
|
|
||||||
from calibre.gui2.actions import InterfaceAction
|
from calibre.gui2.actions import InterfaceAction
|
||||||
from calibre.gui2 import (error_dialog, Dispatcher, warning_dialog, gprefs,
|
from calibre.gui2 import (error_dialog, Dispatcher, warning_dialog, gprefs,
|
||||||
@ -21,7 +20,7 @@ from calibre.gui2.widgets import HistoryLineEdit
|
|||||||
from calibre.utils.config import prefs, tweaks
|
from calibre.utils.config import prefs, tweaks
|
||||||
from calibre.utils.date import now
|
from calibre.utils.date import now
|
||||||
|
|
||||||
class Worker(Thread): # {{{
|
class Worker(Thread): # {{{
|
||||||
|
|
||||||
def __init__(self, ids, db, loc, progress, done, delete_after):
|
def __init__(self, ids, db, loc, progress, done, delete_after):
|
||||||
Thread.__init__(self)
|
Thread.__init__(self)
|
||||||
@ -71,8 +70,10 @@ class Worker(Thread): # {{{
|
|||||||
mi.timestamp = now()
|
mi.timestamp = now()
|
||||||
self.progress(i, mi.title)
|
self.progress(i, mi.title)
|
||||||
fmts = self.db.formats(x, index_is_id=True)
|
fmts = self.db.formats(x, index_is_id=True)
|
||||||
if not fmts: fmts = []
|
if not fmts:
|
||||||
else: fmts = fmts.split(',')
|
fmts = []
|
||||||
|
else:
|
||||||
|
fmts = fmts.split(',')
|
||||||
paths = []
|
paths = []
|
||||||
for fmt in fmts:
|
for fmt in fmts:
|
||||||
p = self.db.format(x, fmt, index_is_id=True,
|
p = self.db.format(x, fmt, index_is_id=True,
|
||||||
@ -82,7 +83,7 @@ class Worker(Thread): # {{{
|
|||||||
automerged = False
|
automerged = False
|
||||||
if prefs['add_formats_to_existing']:
|
if prefs['add_formats_to_existing']:
|
||||||
identical_book_list = newdb.find_identical_books(mi)
|
identical_book_list = newdb.find_identical_books(mi)
|
||||||
if identical_book_list: # books with same author and nearly same title exist in newdb
|
if identical_book_list: # books with same author and nearly same title exist in newdb
|
||||||
self.auto_merged_ids[x] = _('%(title)s by %(author)s')%\
|
self.auto_merged_ids[x] = _('%(title)s by %(author)s')%\
|
||||||
dict(title=mi.title, author=mi.format_field('authors')[1])
|
dict(title=mi.title, author=mi.format_field('authors')[1])
|
||||||
automerged = True
|
automerged = True
|
||||||
@ -127,7 +128,7 @@ class Worker(Thread): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class ChooseLibrary(QDialog): # {{{
|
class ChooseLibrary(QDialog): # {{{
|
||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
super(ChooseLibrary, self).__init__(parent)
|
super(ChooseLibrary, self).__init__(parent)
|
||||||
@ -146,12 +147,19 @@ class ChooseLibrary(QDialog): # {{{
|
|||||||
b.setToolTip(_('Browse for library'))
|
b.setToolTip(_('Browse for library'))
|
||||||
b.clicked.connect(self.browse)
|
b.clicked.connect(self.browse)
|
||||||
l.addWidget(b, 0, 2)
|
l.addWidget(b, 0, 2)
|
||||||
self.c = c = QCheckBox(_('&Delete after copy'))
|
self.bb = bb = QDialogButtonBox(QDialogButtonBox.Cancel)
|
||||||
l.addWidget(c, 1, 0, 1, 3)
|
|
||||||
self.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
|
|
||||||
bb.accepted.connect(self.accept)
|
bb.accepted.connect(self.accept)
|
||||||
bb.rejected.connect(self.reject)
|
bb.rejected.connect(self.reject)
|
||||||
l.addWidget(bb, 2, 0, 1, 3)
|
self.delete_after_copy = False
|
||||||
|
b = bb.addButton(_('&Copy'), bb.AcceptRole)
|
||||||
|
b.setIcon(QIcon(I('edit-copy.png')))
|
||||||
|
b.setToolTip(_('Copy to the specified library'))
|
||||||
|
b2 = bb.addButton(_('&Move'), bb.AcceptRole)
|
||||||
|
b2.clicked.connect(lambda: setattr(self, 'delete_after_copy', True))
|
||||||
|
b2.setIcon(QIcon(I('edit-cut.png')))
|
||||||
|
b2.setToolTip(_('Copy to the specified library and delete from the current library'))
|
||||||
|
b.setDefault(True)
|
||||||
|
l.addWidget(bb, 1, 0, 1, 3)
|
||||||
le.setMinimumWidth(350)
|
le.setMinimumWidth(350)
|
||||||
self.resize(self.sizeHint())
|
self.resize(self.sizeHint())
|
||||||
|
|
||||||
@ -163,7 +171,7 @@ class ChooseLibrary(QDialog): # {{{
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def args(self):
|
def args(self):
|
||||||
return (unicode(self.le.text()), self.c.isChecked())
|
return (unicode(self.le.text()), self.delete_after_copy)
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class CopyToLibraryAction(InterfaceAction):
|
class CopyToLibraryAction(InterfaceAction):
|
||||||
@ -204,7 +212,7 @@ class CopyToLibraryAction(InterfaceAction):
|
|||||||
self.menu.addAction(name, partial(self.copy_to_library,
|
self.menu.addAction(name, partial(self.copy_to_library,
|
||||||
loc))
|
loc))
|
||||||
self.menu.addAction(name + ' ' + _('(delete after copy)'),
|
self.menu.addAction(name + ' ' + _('(delete after copy)'),
|
||||||
partial(self.copy_to_library, loc, delete_after=True))
|
partial(self.copy_to_library, loc, delete_after=True))
|
||||||
self.menu.addSeparator()
|
self.menu.addSeparator()
|
||||||
|
|
||||||
self.menu.addAction(_('Choose library by path...'), self.choose_library)
|
self.menu.addAction(_('Choose library by path...'), self.choose_library)
|
||||||
@ -214,6 +222,8 @@ class CopyToLibraryAction(InterfaceAction):
|
|||||||
d = ChooseLibrary(self.gui)
|
d = ChooseLibrary(self.gui)
|
||||||
if d.exec_() == d.Accepted:
|
if d.exec_() == d.Accepted:
|
||||||
path, delete_after = d.args
|
path, delete_after = d.args
|
||||||
|
if not path:
|
||||||
|
return
|
||||||
db = self.gui.library_view.model().db
|
db = self.gui.library_view.model().db
|
||||||
current = os.path.normcase(os.path.abspath(db.library_path))
|
current = os.path.normcase(os.path.abspath(db.library_path))
|
||||||
if current == os.path.normcase(os.path.abspath(path)):
|
if current == os.path.normcase(os.path.abspath(path)):
|
||||||
|
@ -8,7 +8,7 @@ from functools import partial
|
|||||||
|
|
||||||
from PyQt4.Qt import (
|
from PyQt4.Qt import (
|
||||||
Qt, QMenu, QPoint, QIcon, QDialog, QGridLayout, QLabel, QLineEdit,
|
Qt, QMenu, QPoint, QIcon, QDialog, QGridLayout, QLabel, QLineEdit,
|
||||||
QDialogButtonBox, QSize, QVBoxLayout, QListWidget, QStringList)
|
QDialogButtonBox, QSize, QVBoxLayout, QListWidget, QStringList, QCheckBox)
|
||||||
|
|
||||||
from calibre.gui2 import error_dialog, question_dialog
|
from calibre.gui2 import error_dialog, question_dialog
|
||||||
from calibre.gui2.widgets import ComboBoxWithHelp
|
from calibre.gui2.widgets import ComboBoxWithHelp
|
||||||
@ -31,6 +31,9 @@ class SelectNames(QDialog): # {{{
|
|||||||
self._names.setSelectionMode(self._names.ExtendedSelection)
|
self._names.setSelectionMode(self._names.ExtendedSelection)
|
||||||
l.addWidget(self._names)
|
l.addWidget(self._names)
|
||||||
|
|
||||||
|
self._and = QCheckBox(_('Match all selected %s names')%txt)
|
||||||
|
l.addWidget(self._and)
|
||||||
|
|
||||||
self.bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
self.bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
||||||
self.bb.accepted.connect(self.accept)
|
self.bb.accepted.connect(self.accept)
|
||||||
self.bb.rejected.connect(self.reject)
|
self.bb.rejected.connect(self.reject)
|
||||||
@ -42,6 +45,11 @@ class SelectNames(QDialog): # {{{
|
|||||||
def names(self):
|
def names(self):
|
||||||
for item in self._names.selectedItems():
|
for item in self._names.selectedItems():
|
||||||
yield unicode(item.data(Qt.DisplayRole).toString())
|
yield unicode(item.data(Qt.DisplayRole).toString())
|
||||||
|
|
||||||
|
@property
|
||||||
|
def match_type(self):
|
||||||
|
return ' and ' if self._and.isChecked() else ' or '
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
MAX_VIRTUAL_LIBRARY_NAME_LENGTH = 40
|
MAX_VIRTUAL_LIBRARY_NAME_LENGTH = 40
|
||||||
@ -154,7 +162,9 @@ class CreateVirtualLibrary(QDialog): # {{{
|
|||||||
search = ['%s:"=%s"'%(prefix, x.replace('"', '\\"')) for x in d.names]
|
search = ['%s:"=%s"'%(prefix, x.replace('"', '\\"')) for x in d.names]
|
||||||
if search:
|
if search:
|
||||||
self.vl_name.setText(d.names.next())
|
self.vl_name.setText(d.names.next())
|
||||||
self.vl_text.setText(' or '.join(search))
|
self.vl_text.setText(d.match_type.join(search))
|
||||||
|
self.vl_text.setCursorPosition(0)
|
||||||
|
self.vl_name.setCursorPosition(0)
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
n = unicode(self.vl_name.text()).strip()
|
n = unicode(self.vl_name.text()).strip()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user