Sync to trunk.

This commit is contained in:
John Schember 2011-04-17 11:10:38 -04:00
commit f747483f3d
19 changed files with 192 additions and 173 deletions

View File

@ -12,6 +12,7 @@ from Queue import Empty
from calibre.customize.conversion import InputFormatPlugin, OptionRecommendation
from calibre import extract, CurrentDir, prints
from calibre.constants import filesystem_encoding
from calibre.ptempfile import PersistentTemporaryDirectory
from calibre.utils.ipc.server import Server
from calibre.utils.ipc.job import ParallelJob
@ -21,6 +22,10 @@ def extract_comic(path_to_comic_file):
Un-archive the comic file.
'''
tdir = PersistentTemporaryDirectory(suffix='_comic_extract')
if not isinstance(tdir, unicode):
# Needed in case the zip file has wrongly encoded unicode file/dir
# names
tdir = tdir.decode(filesystem_encoding)
extract(path_to_comic_file, tdir)
return tdir

View File

@ -716,6 +716,7 @@ class MobiReader(object):
ent_pat = re.compile(r'&(\S+?);')
if elems:
tocobj = TOC()
found = False
reached = False
for x in root.iter():
if x == elems[-1]:
@ -732,7 +733,8 @@ class MobiReader(object):
text = ent_pat.sub(entity_to_unicode, text)
tocobj.add_item(toc.partition('#')[0], href[1:],
text)
if reached and x.get('class', None) == 'mbp_pagebreak':
found = True
if reached and found and x.get('class', None) == 'mbp_pagebreak':
break
if tocobj is not None:
opf.set_toc(tocobj)

View File

@ -8,14 +8,14 @@ __docformat__ = 'restructuredtext en'
from functools import partial
from PyQt4.Qt import Qt, QMenu, QToolButton, QDialog, QVBoxLayout
from PyQt4.Qt import QMenu
from calibre.gui2.actions import InterfaceAction
class StoreAction(InterfaceAction):
name = 'Store'
action_spec = (_('Store'), 'store.png', None, None)
action_spec = (_('Get books'), 'store.png', None, None)
def genesis(self):
self.qaction.triggered.connect(self.search)

View File

@ -68,7 +68,7 @@ class DaysOfWeek(Base):
def initialize(self, typ=None, val=None):
if typ is None:
typ = 'day/time'
val = (-1, 9, 0)
val = (-1, 6, 0)
if typ == 'day/time':
val = convert_day_time_schedule(val)
@ -118,7 +118,7 @@ class DaysOfMonth(Base):
def initialize(self, typ=None, val=None):
if val is None:
val = ((1,), 9, 0)
val = ((1,), 6, 0)
days_of_month, hour, minute = val
self.days.setText(', '.join(map(str, map(int, days_of_month))))
self.time.setTime(QTime(hour, minute))
@ -380,7 +380,7 @@ class SchedulerDialog(QDialog, Ui_Dialog):
if d < timedelta(days=366):
ld_text = tm
else:
typ, sch = 'day/time', (-1, 9, 0)
typ, sch = 'day/time', (-1, 6, 0)
sch_widget = {'day/time': 0, 'days_of_week': 0, 'days_of_month':1,
'interval':2}[typ]
rb = getattr(self, list(self.SCHEDULE_TYPES)[sch_widget])

View File

@ -200,13 +200,6 @@ class SearchBar(QWidget): # {{{
x.setIcon(QIcon(I('arrow-down.png')))
l.addWidget(x)
x = parent.search_options_button = QToolButton(self)
x.setIcon(QIcon(I('config.png')))
x.setObjectName("search_option_button")
l.addWidget(x)
x.setToolTip(_("Change the way searching for books works"))
x.setVisible(False)
x = parent.saved_search = SavedSearchBox(self)
x.setMaximumSize(QSize(150, 16777215))
x.setMinimumContentsLength(15)
@ -324,6 +317,8 @@ class BaseToolBar(QToolBar): # {{{
QToolBar.resizeEvent(self, ev)
style = self.get_text_style()
self.setToolButtonStyle(style)
if hasattr(self, 'd_widget'):
self.d_widget.filler.setVisible(style != Qt.ToolButtonIconOnly)
def get_text_style(self):
style = Qt.ToolButtonTextUnderIcon
@ -406,7 +401,8 @@ class ToolBar(BaseToolBar): # {{{
self.d_widget.layout().addWidget(self.donate_button)
if isosx:
self.d_widget.setStyleSheet('QWidget, QToolButton {background-color: none; border: none; }')
self.d_widget.layout().addWidget(QLabel(u'\u00a0'))
self.d_widget.filler = QLabel(u'\u00a0')
self.d_widget.layout().addWidget(self.d_widget.filler)
bar.addWidget(self.d_widget)
self.showing_donate = True
elif what in self.gui.iactions:

View File

@ -743,6 +743,8 @@ class BooksView(QTableView): # {{{
id_to_select = self._model.get_current_highlighted_id()
if id_to_select is not None:
self.select_rows([id_to_select], using_ids=True)
elif self._model.highlight_only:
self.clearSelection()
self.setFocus(Qt.OtherFocusReason)
def connect_to_search_box(self, sb, search_done):

View File

@ -222,7 +222,8 @@ class AuthorSortEdit(EnLineEdit):
'red, then the authors and this text do not match.')
LABEL = _('Author s&ort:')
def __init__(self, parent, authors_edit, autogen_button, db):
def __init__(self, parent, authors_edit, autogen_button, db,
copy_a_to_as_action, copy_as_to_a_action):
EnLineEdit.__init__(self, parent)
self.authors_edit = authors_edit
self.db = db
@ -241,6 +242,8 @@ class AuthorSortEdit(EnLineEdit):
self.textChanged.connect(self.update_state)
autogen_button.clicked.connect(self.auto_generate)
copy_a_to_as_action.triggered.connect(self.auto_generate)
copy_as_to_a_action.triggered.connect(self.copy_to_authors)
self.update_state()
@dynamic_property
@ -273,6 +276,14 @@ class AuthorSortEdit(EnLineEdit):
self.setToolTip(tt)
self.setWhatsThis(tt)
def copy_to_authors(self):
aus = self.current_val
if aus:
ln, _, rest = aus.partition(',')
if rest:
au = rest.strip() + ' ' + ln.strip()
self.authors_edit.current_val = [au]
def auto_generate(self, *args):
au = unicode(self.authors_edit.text())
au = re.sub(r'\s+et al\.$', '', au)

View File

@ -13,7 +13,7 @@ from functools import partial
from PyQt4.Qt import (Qt, QVBoxLayout, QHBoxLayout, QWidget, QPushButton,
QGridLayout, pyqtSignal, QDialogButtonBox, QScrollArea, QFont,
QTabWidget, QIcon, QToolButton, QSplitter, QGroupBox, QSpacerItem,
QSizePolicy, QPalette, QFrame, QSize, QKeySequence)
QSizePolicy, QPalette, QFrame, QSize, QKeySequence, QMenu)
from calibre.ebooks.metadata import authors_to_string, string_to_authors
from calibre.gui2 import ResizableDialog, error_dialog, gprefs, pixmap_to_data
@ -102,15 +102,19 @@ class MetadataSingleDialogBase(ResizableDialog):
self.deduce_title_sort_button)
self.basic_metadata_widgets.extend([self.title, self.title_sort])
self.authors = AuthorsEdit(self)
self.deduce_author_sort_button = QToolButton(self)
self.deduce_author_sort_button.setToolTip(_(
self.deduce_author_sort_button = b = QToolButton(self)
b.setToolTip(_(
'Automatically create the author sort entry based on the current'
' author entry.\n'
'Using this button to create author sort will change author sort from'
' red to green.'))
self.author_sort = AuthorSortEdit(self, self.authors,
self.deduce_author_sort_button, self.db)
b.m = m = QMenu()
ac = m.addAction(QIcon(I('forward.png')), _('Set author sort from author'))
ac2 = m.addAction(QIcon(I('back.png')), _('Set author from author sort'))
b.setMenu(m)
self.authors = AuthorsEdit(self)
self.author_sort = AuthorSortEdit(self, self.authors, b, self.db, ac,
ac2)
self.basic_metadata_widgets.extend([self.authors, self.author_sort])
self.swap_title_author_button = QToolButton(self)

View File

@ -319,9 +319,12 @@ def show_config_widget(category, name, gui=None, show_restart_msg=False,
:return: True iff a restart is required for the changes made by the user to
take effect
'''
from calibre.gui2 import gprefs
pl = get_plugin(category, name)
d = ConfigDialog(parent)
d.resize(750, 550)
conf_name = 'config_widget_dialog_geometry_%s_%s'%(category, name)
geom = gprefs.get(conf_name, None)
d.setWindowTitle(_('Configure ') + name)
d.setWindowIcon(QIcon(I('config.png')))
bb = QDialogButtonBox(d)
@ -345,7 +348,11 @@ def show_config_widget(category, name, gui=None, show_restart_msg=False,
mygui = True
w.genesis(gui)
w.initialize()
if geom is not None:
d.restoreGeometry(geom)
d.exec_()
geom = bytearray(d.saveGeometry())
gprefs[conf_name] = geom
rr = getattr(d, 'restart_required', False)
if show_restart_msg and rr:
from calibre.gui2 import warning_dialog

View File

@ -364,7 +364,6 @@ class SearchBoxMixin(object): # {{{
unicode(self.search.toolTip())))
self.advanced_search_button.setStatusTip(self.advanced_search_button.toolTip())
self.clear_button.setStatusTip(self.clear_button.toolTip())
self.search_options_button.clicked.connect(self.search_options_button_clicked)
self.set_highlight_only_button_icon()
self.highlight_only_button.clicked.connect(self.highlight_only_clicked)
tt = _('Enable or disable search highlighting.') + '<br><br>'
@ -374,6 +373,8 @@ class SearchBoxMixin(object): # {{{
def highlight_only_clicked(self, state):
config['highlight_search_matches'] = not config['highlight_search_matches']
self.set_highlight_only_button_icon()
self.search.do_search()
self.focus_to_library()
def set_highlight_only_button_icon(self):
if config['highlight_search_matches']:
@ -404,10 +405,6 @@ class SearchBoxMixin(object): # {{{
self.search.do_search()
self.focus_to_library()
def search_options_button_clicked(self):
self.iactions['Preferences'].do_config(initial_plugin=('Interface',
'Search'), close_after_initial=True)
def focus_to_library(self):
self.current_view().setFocus(Qt.OtherFocusReason)

View File

@ -6,7 +6,6 @@ __license__ = 'GPL 3'
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
__docformat__ = 'restructuredtext en'
import re
import urllib2
from contextlib import closing

View File

@ -13,9 +13,8 @@ from random import shuffle
from threading import Thread
from Queue import Queue
from PyQt4.Qt import Qt, QAbstractItemModel, QDialog, QTimer, QVariant, \
QModelIndex, QPixmap, QSize, QCheckBox, QVBoxLayout, QHBoxLayout, \
QPushButton, QString, QByteArray
from PyQt4.Qt import (Qt, QAbstractItemModel, QDialog, QTimer, QVariant,
QModelIndex, QPixmap, QSize, QCheckBox, QVBoxLayout)
from calibre import browser
from calibre.gui2 import NONE

View File

@ -9,8 +9,8 @@ __docformat__ = 'restructuredtext en'
import os
from urlparse import urlparse
from PyQt4.Qt import QWebView, QWebPage, QNetworkCookieJar, QNetworkRequest, QString, \
QFileDialog, QNetworkProxy
from PyQt4.Qt import (QWebView, QWebPage, QNetworkCookieJar,
QFileDialog, QNetworkProxy)
from calibre import USER_AGENT, get_proxies, get_download_filename
from calibre.ebooks import BOOK_EXTENSIONS

View File

@ -15,7 +15,7 @@ from functools import partial
from PyQt4.Qt import (Qt, QTreeView, QApplication, pyqtSignal, QFont, QSize,
QIcon, QPoint, QVBoxLayout, QHBoxLayout, QComboBox, QTimer,
QAbstractItemModel, QVariant, QModelIndex, QMenu, QFrame,
QWidget, QItemDelegate, QString, QLabel,
QWidget, QItemDelegate, QString, QLabel, QPushButton,
QShortcut, QKeySequence, SIGNAL, QMimeData, QToolButton)
from calibre.ebooks.metadata import title_sort
@ -1809,9 +1809,6 @@ class TagsModel(QAbstractItemModel): # {{{
# }}}
category_managers = (
)
class TagBrowserMixin(object): # {{{
def __init__(self, db):
@ -1833,20 +1830,23 @@ class TagBrowserMixin(object): # {{{
self.tags_view.restriction_error.connect(self.do_restriction_error,
type=Qt.QueuedConnection)
for text, func, args in (
(_('Manage Authors'), self.do_author_sort_edit, (self,
None)),
(_('Manage Series'), self.do_tags_list_edit, (None,
'series')),
(_('Manage Publishers'), self.do_tags_list_edit, (None,
'publisher')),
(_('Manage Tags'), self.do_tags_list_edit, (None, 'tags')),
for text, func, args, cat_name in (
(_('Manage Authors'),
self.do_author_sort_edit, (self, None), 'authors'),
(_('Manage Series'),
self.do_tags_list_edit, (None, 'series'), 'series'),
(_('Manage Publishers'),
self.do_tags_list_edit, (None, 'publisher'), 'publisher'),
(_('Manage Tags'),
self.do_tags_list_edit, (None, 'tags'), 'tags'),
(_('Manage User Categories'),
self.do_edit_user_categories, (None,)),
(_('Manage Saved Searches'), self.do_saved_search_edit,
(None,))
self.do_edit_user_categories, (None,), 'user:'),
(_('Manage Saved Searches'),
self.do_saved_search_edit, (None,), 'search')
):
self.manage_items_button.menu().addAction(text, partial(func, *args))
self.manage_items_button.menu().addAction(
QIcon(I(category_icon_map[cat_name])),
text, partial(func, *args))
def do_restriction_error(self):
error_dialog(self.tags_view, _('Invalid search restriction'),
@ -2166,11 +2166,9 @@ class TagBrowserWidget(QWidget): # {{{
parent.tag_match.setStatusTip(parent.tag_match.toolTip())
l = parent.manage_items_button = QToolButton(self)
l.setIcon(QIcon(I('tags.png')))
l = parent.manage_items_button = QPushButton(self)
l.setStyleSheet('QPushButton {text-align: left; }')
l.setText(_('Manage authors, tags, etc'))
l.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
l.setPopupMode(l.InstantPopup)
l.setToolTip(_('All of these category_managers are available by right-clicking '
'on items in the tag browser above'))
l.m = QMenu()

View File

@ -529,10 +529,10 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
action.location_selected(location)
if location == 'library':
self.search_restriction.setEnabled(True)
self.search_options_button.setEnabled(True)
self.highlight_only_button.setEnabled(True)
else:
self.search_restriction.setEnabled(False)
self.search_options_button.setEnabled(False)
self.highlight_only_button.setEnabled(False)
# Reset the view in case something changed while it was invisible
self.current_view().reset()
self.set_number_of_books_shown()

View File

@ -426,7 +426,7 @@ def do_show_metadata(db, id, as_opf):
mi = OPFCreator(os.getcwd(), mi)
mi.render(sys.stdout)
else:
print unicode(mi).encode(preferred_encoding)
prints(unicode(mi))
def show_metadata_option_parser():
parser = get_parser(_(

View File

@ -854,7 +854,6 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
mi.uuid = row[fm['uuid']]
mi.title_sort = row[fm['sort']]
mi.last_modified = row[fm['last_modified']]
mi.size = row[fm['size']]
formats = row[fm['formats']]
if not formats:
formats = None