merge from trunk

This commit is contained in:
Lee 2011-04-19 02:08:17 +08:00
commit d03d831149
9 changed files with 178 additions and 58 deletions

View File

@ -6,12 +6,13 @@ __copyright__ = 'Copyright 2010 Starson17'
www.arcamax.com www.arcamax.com
''' '''
from calibre.web.feeds.news import BasicNewsRecipe from calibre.web.feeds.news import BasicNewsRecipe
from calibre.ebooks.BeautifulSoup import Tag
class Arcamax(BasicNewsRecipe): class Arcamax(BasicNewsRecipe):
title = 'Arcamax' title = 'Arcamax'
__author__ = 'Starson17' __author__ = 'Starson17'
__version__ = '1.03' __version__ = '1.04'
__date__ = '25 November 2010' __date__ = '18 April 2011'
description = u'Family Friendly Comics - Customize for more days/comics: Defaults to 7 days, 25 comics - 20 general, 5 editorial.' description = u'Family Friendly Comics - Customize for more days/comics: Defaults to 7 days, 25 comics - 20 general, 5 editorial.'
category = 'news, comics' category = 'news, comics'
language = 'en' language = 'en'
@ -30,7 +31,14 @@ class Arcamax(BasicNewsRecipe):
, 'language' : language , 'language' : language
} }
keep_only_tags = [dict(name='div', attrs={'class':['toon']}), keep_only_tags = [dict(name='div', attrs={'class':['comics-header']}),
dict(name='b', attrs={'class':['current']}),
dict(name='article', attrs={'class':['comic']}),
]
remove_tags = [dict(name='div', attrs={'id':['comicfull' ]}),
dict(name='div', attrs={'class':['calendar' ]}),
dict(name='nav', attrs={'class':['calendar-nav' ]}),
] ]
def parse_index(self): def parse_index(self):
@ -71,7 +79,6 @@ class Arcamax(BasicNewsRecipe):
#(u"Rugrats", u"http://www.arcamax.com/rugrats"), #(u"Rugrats", u"http://www.arcamax.com/rugrats"),
(u"Speed Bump", u"http://www.arcamax.com/speedbump"), (u"Speed Bump", u"http://www.arcamax.com/speedbump"),
(u"Wizard of Id", u"http://www.arcamax.com/wizardofid"), (u"Wizard of Id", u"http://www.arcamax.com/wizardofid"),
(u"Dilbert", u"http://www.arcamax.com/dilbert"),
(u"Zits", u"http://www.arcamax.com/zits"), (u"Zits", u"http://www.arcamax.com/zits"),
]: ]:
articles = self.make_links(url) articles = self.make_links(url)
@ -86,24 +93,37 @@ class Arcamax(BasicNewsRecipe):
for page in pages: for page in pages:
page_soup = self.index_to_soup(url) page_soup = self.index_to_soup(url)
if page_soup: if page_soup:
title = page_soup.find(name='div', attrs={'class':'toon'}).p.img['alt'] title = page_soup.find(name='div', attrs={'class':'comics-header'}).h1.contents[0]
page_url = url page_url = url
prev_page_url = 'http://www.arcamax.com' + page_soup.find('a', attrs={'class':'next'}, text='Previous').parent['href'] # orig prev_page_url = 'http://www.arcamax.com' + page_soup.find('a', attrs={'class':'prev'}, text='Previous').parent['href']
current_articles.append({'title': title, 'url': page_url, 'description':'', 'date':''}) prev_page_url = 'http://www.arcamax.com' + page_soup.find('span', text='Previous').parent.parent['href']
date = self.tag_to_string(page_soup.find(name='b', attrs={'class':['current']}))
current_articles.append({'title': title, 'url': page_url, 'description':'', 'date': date})
url = prev_page_url url = prev_page_url
current_articles.reverse() current_articles.reverse()
return current_articles return current_articles
def preprocess_html(self, soup): def preprocess_html(self, soup):
main_comic = soup.find('p',attrs={'class':'m0'}) for img_tag in soup.findAll('img'):
if main_comic.a['target'] == '_blank': parent_tag = img_tag.parent
main_comic.a.img['id'] = 'main_comic' if parent_tag.name == 'a':
new_tag = Tag(soup,'p')
new_tag.insert(0,img_tag)
parent_tag.replaceWith(new_tag)
elif parent_tag.name == 'p':
if not self.tag_to_string(parent_tag) == '':
new_div = Tag(soup,'div')
new_tag = Tag(soup,'p')
new_tag.insert(0,img_tag)
parent_tag.replaceWith(new_div)
new_div.insert(0,new_tag)
new_div.insert(1,parent_tag)
return soup return soup
extra_css = ''' extra_css = '''
h1{font-family:Arial,Helvetica,sans-serif; font-weight:bold;font-size:large;} h1{font-family:Arial,Helvetica,sans-serif; font-weight:bold;font-size:large;}
h2{font-family:Arial,Helvetica,sans-serif; font-weight:normal;font-size:small;} h2{font-family:Arial,Helvetica,sans-serif; font-weight:normal;font-size:small;}
img#main_comic {max-width:100%; min-width:100%;} img {max-width:100%; min-width:100%;}
p{font-family:Arial,Helvetica,sans-serif;font-size:small;} p{font-family:Arial,Helvetica,sans-serif;font-size:small;}
body{font-family:Helvetica,Arial,sans-serif;font-size:small;} body{font-family:Helvetica,Arial,sans-serif;font-size:small;}
''' '''

View File

@ -67,6 +67,23 @@ def authors_test(authors):
return test return test
def series_test(series, series_index):
series = series.lower()
def test(mi):
ms = mi.series.lower() if mi.series else ''
if (ms == series) and (series_index == mi.series_index):
return True
if mi.series:
prints('Series test failed. Expected: \'%s [%d]\' found \'%s[%d]\''% \
(series, series_index, ms, mi.series_index))
else:
prints('Series test failed. Expected: \'%s [%d]\' found no series'% \
(series, series_index))
return False
return test
def init_test(tdir_name): def init_test(tdir_name):
tdir = tempfile.gettempdir() tdir = tempfile.gettempdir()
lf = os.path.join(tdir, tdir_name.replace(' ', '')+'_identify_test.txt') lf = os.path.join(tdir, tdir_name.replace(' ', '')+'_identify_test.txt')

View File

@ -37,8 +37,6 @@ class EditMetadataAction(InterfaceAction):
md.addSeparator() md.addSeparator()
if test_eight_code: if test_eight_code:
dall = self.download_metadata dall = self.download_metadata
dident = partial(self.download_metadata, covers=False)
dcovers = partial(self.download_metadata, identify=False)
else: else:
dall = partial(self.download_metadata_old, False, covers=True) dall = partial(self.download_metadata_old, False, covers=True)
dident = partial(self.download_metadata_old, False, covers=False) dident = partial(self.download_metadata_old, False, covers=False)
@ -47,9 +45,9 @@ class EditMetadataAction(InterfaceAction):
md.addAction(_('Download metadata and covers'), dall, md.addAction(_('Download metadata and covers'), dall,
Qt.ControlModifier+Qt.Key_D) Qt.ControlModifier+Qt.Key_D)
if not test_eight_code:
md.addAction(_('Download only metadata'), dident) md.addAction(_('Download only metadata'), dident)
md.addAction(_('Download only covers'), dcovers) md.addAction(_('Download only covers'), dcovers)
if not test_eight_code:
md.addAction(_('Download only social metadata'), md.addAction(_('Download only social metadata'),
partial(self.download_metadata_old, False, covers=False, partial(self.download_metadata_old, False, covers=False,
set_metadata=False, set_social_metadata=True)) set_metadata=False, set_social_metadata=True))
@ -80,7 +78,7 @@ class EditMetadataAction(InterfaceAction):
self.qaction.setEnabled(enabled) self.qaction.setEnabled(enabled)
self.action_merge.setEnabled(enabled) self.action_merge.setEnabled(enabled)
def download_metadata(self, identify=True, covers=True, ids=None): def download_metadata(self, ids=None):
if ids is None: if ids is None:
rows = self.gui.library_view.selectionModel().selectedRows() rows = self.gui.library_view.selectionModel().selectedRows()
if not rows or len(rows) == 0: if not rows or len(rows) == 0:
@ -90,7 +88,7 @@ class EditMetadataAction(InterfaceAction):
ids = [db.id(row.row()) for row in rows] ids = [db.id(row.row()) for row in rows]
from calibre.gui2.metadata.bulk_download2 import start_download from calibre.gui2.metadata.bulk_download2 import start_download
start_download(self.gui, ids, start_download(self.gui, ids,
Dispatcher(self.bulk_metadata_downloaded), identify, covers) Dispatcher(self.bulk_metadata_downloaded))
def bulk_metadata_downloaded(self, job): def bulk_metadata_downloaded(self, job):
if job.failed: if job.failed:

View File

@ -289,6 +289,7 @@ class Series(Base):
values = self.all_values = list(self.db.all_custom(num=self.col_id)) values = self.all_values = list(self.db.all_custom(num=self.col_id))
values.sort(key=sort_key) values.sort(key=sort_key)
w = MultiCompleteComboBox(parent) w = MultiCompleteComboBox(parent)
w.set_separator(None)
w.setSizeAdjustPolicy(w.AdjustToMinimumContentsLengthWithIcon) w.setSizeAdjustPolicy(w.AdjustToMinimumContentsLengthWithIcon)
w.setMinimumContentsLength(25) w.setMinimumContentsLength(25)
self.name_widget = w self.name_widget = w

View File

@ -12,7 +12,7 @@ from zipfile import ZipFile, ZIP_DEFLATED, ZIP_STORED
from PyQt4.Qt import QDialog from PyQt4.Qt import QDialog
from calibre.constants import isosx, iswindows from calibre.constants import isosx
from calibre.gui2 import open_local_file from calibre.gui2 import open_local_file
from calibre.gui2.dialogs.tweak_epub_ui import Ui_Dialog from calibre.gui2.dialogs.tweak_epub_ui import Ui_Dialog
from calibre.libunzip import extract as zipextract from calibre.libunzip import extract as zipextract

View File

@ -278,11 +278,13 @@ class AuthorSortEdit(EnLineEdit):
def copy_to_authors(self): def copy_to_authors(self):
aus = self.current_val aus = self.current_val
meth = tweaks['author_sort_copy_method']
if aus: if aus:
ln, _, rest = aus.partition(',') ln, _, rest = aus.partition(',')
if rest: if rest:
au = rest.strip() + ' ' + ln.strip() if meth in ('invert', 'nocomma', 'comma'):
self.authors_edit.current_val = [au] aus = rest.strip() + ' ' + ln.strip()
self.authors_edit.current_val = [aus]
def auto_generate(self, *args): def auto_generate(self, *args):
au = unicode(self.authors_edit.text()) au = unicode(self.authors_edit.text())
@ -465,16 +467,22 @@ class FormatsManager(QWidget): # {{{
self.metadata_from_format_button = QToolButton(self) self.metadata_from_format_button = QToolButton(self)
self.metadata_from_format_button.setIcon(QIcon(I('edit_input.png'))) self.metadata_from_format_button.setIcon(QIcon(I('edit_input.png')))
self.metadata_from_format_button.setIconSize(QSize(32, 32)) self.metadata_from_format_button.setIconSize(QSize(32, 32))
self.metadata_from_format_button.setToolTip(
_('Set metadata for the book from the selected format'))
self.add_format_button = QToolButton(self) self.add_format_button = QToolButton(self)
self.add_format_button.setIcon(QIcon(I('add_book.png'))) self.add_format_button.setIcon(QIcon(I('add_book.png')))
self.add_format_button.setIconSize(QSize(32, 32)) self.add_format_button.setIconSize(QSize(32, 32))
self.add_format_button.clicked.connect(self.add_format) self.add_format_button.clicked.connect(self.add_format)
self.add_format_button.setToolTip(
_('Add a format to this book'))
self.remove_format_button = QToolButton(self) self.remove_format_button = QToolButton(self)
self.remove_format_button.setIcon(QIcon(I('trash.png'))) self.remove_format_button.setIcon(QIcon(I('trash.png')))
self.remove_format_button.setIconSize(QSize(32, 32)) self.remove_format_button.setIconSize(QSize(32, 32))
self.remove_format_button.clicked.connect(self.remove_format) self.remove_format_button.clicked.connect(self.remove_format)
self.remove_format_button.setToolTip(
_('Remove the selected format from this book'))
self.formats = FormatList(self) self.formats = FormatList(self)
self.formats.setAcceptDrops(True) self.formats.setAcceptDrops(True)
@ -939,7 +947,13 @@ class IdentifiersEdit(QLineEdit): # {{{
def fset(self, val): def fset(self, val):
if not val: if not val:
val = {} val = {}
txt = ', '.join(['%s:%s'%(k, v) for k, v in val.iteritems()]) def keygen(x):
x = x[0]
if x == 'isbn':
x = '00isbn'
return x
ids = sorted(val.iteritems(), key=keygen)
txt = ', '.join(['%s:%s'%(k, v) for k, v in ids])
self.setText(txt.strip()) self.setText(txt.strip())
self.setCursorPosition(0) self.setCursorPosition(0)
return property(fget=fget, fset=fset) return property(fget=fget, fset=fset)
@ -959,7 +973,7 @@ class IdentifiersEdit(QLineEdit): # {{{
tt = self.BASE_TT tt = self.BASE_TT
extra = '' extra = ''
if not isbn: if not isbn:
col = 'rgba(0,255,0,0%)' col = 'none'
elif check_isbn(isbn) is not None: elif check_isbn(isbn) is not None:
col = 'rgba(0,255,0,20%)' col = 'rgba(0,255,0,20%)'
extra = '\n\n'+_('This ISBN number is valid') extra = '\n\n'+_('This ISBN number is valid')

View File

@ -12,7 +12,8 @@ from functools import partial
from itertools import izip from itertools import izip
from PyQt4.Qt import (QIcon, QDialog, QVBoxLayout, QTextBrowser, QSize, from PyQt4.Qt import (QIcon, QDialog, QVBoxLayout, QTextBrowser, QSize,
QDialogButtonBox, QApplication, QTimer, QLabel, QProgressBar) QDialogButtonBox, QApplication, QTimer, QLabel, QProgressBar,
QGridLayout, QPixmap, Qt)
from calibre.gui2.dialogs.message_box import MessageBox from calibre.gui2.dialogs.message_box import MessageBox
from calibre.gui2.threaded_jobs import ThreadedJob from calibre.gui2.threaded_jobs import ThreadedJob
@ -25,37 +26,86 @@ from calibre.ebooks.metadata.book.base import Metadata
from calibre.customize.ui import metadata_plugins from calibre.customize.ui import metadata_plugins
from calibre.ptempfile import PersistentTemporaryFile from calibre.ptempfile import PersistentTemporaryFile
# Start download {{{
def show_config(gui, parent): def show_config(gui, parent):
from calibre.gui2.preferences import show_config_widget from calibre.gui2.preferences import show_config_widget
show_config_widget('Sharing', 'Metadata download', parent=parent, show_config_widget('Sharing', 'Metadata download', parent=parent,
gui=gui, never_shutdown=True) gui=gui, never_shutdown=True)
def start_download(gui, ids, callback, identify, covers): class ConfirmDialog(QDialog):
q = MessageBox(MessageBox.QUESTION, _('Schedule download?'),
def __init__(self, ids, parent):
QDialog.__init__(self, parent)
self.setWindowTitle(_('Schedule download?'))
self.setWindowIcon(QIcon(I('dialog_question.png')))
l = self.l = QGridLayout()
self.setLayout(l)
i = QLabel(self)
i.setPixmap(QPixmap(I('dialog_question.png')))
l.addWidget(i, 0, 0)
t = QLabel(
'<p>'+_('The download of metadata for the <b>%d selected book(s)</b> will' '<p>'+_('The download of metadata for the <b>%d selected book(s)</b> will'
' run in the background. Proceed?')%len(ids) + ' run in the background. Proceed?')%len(ids) +
'<p>'+_('You can monitor the progress of the download ' '<p>'+_('You can monitor the progress of the download '
'by clicking the rotating spinner in the bottom right ' 'by clicking the rotating spinner in the bottom right '
'corner.') + 'corner.') +
'<p>'+_('When the download completes you will be asked for' '<p>'+_('When the download completes you will be asked for'
' confirmation before calibre applies the downloaded metadata.'), ' confirmation before calibre applies the downloaded metadata.')
show_copy_button=False, parent=gui) )
b = q.bb.addButton(_('Configure download'), q.bb.ActionRole) t.setWordWrap(True)
b.setIcon(QIcon(I('config.png'))) l.addWidget(t, 0, 1)
b.clicked.connect(partial(show_config, gui, q)) l.setColumnStretch(0, 1)
q.det_msg_toggle.setVisible(False) l.setColumnStretch(1, 100)
ret = q.exec_() self.identify = self.covers = True
b.clicked.disconnect() self.bb = QDialogButtonBox(QDialogButtonBox.Cancel)
if ret != q.Accepted: self.bb.rejected.connect(self.reject)
b = self.bb.addButton(_('Download only &metadata'),
self.bb.AcceptRole)
b.clicked.connect(self.only_metadata)
b.setIcon(QIcon(I('edit_input.png')))
b = self.bb.addButton(_('Download only &covers'),
self.bb.AcceptRole)
b.clicked.connect(self.only_covers)
b.setIcon(QIcon(I('default_cover.png')))
b = self.b = self.bb.addButton(_('&Configure download'), self.bb.ActionRole)
b.setIcon(QIcon(I('config.png')))
b.clicked.connect(partial(show_config, parent, self))
l.addWidget(self.bb, 1, 0, 1, 2)
b = self.bb.addButton(_('Download &both'),
self.bb.AcceptRole)
b.clicked.connect(self.accept)
b.setDefault(True)
b.setAutoDefault(True)
b.setIcon(QIcon(I('ok.png')))
self.resize(self.sizeHint())
b.setFocus(Qt.OtherFocusReason)
def only_metadata(self):
self.covers = False
self.accept()
def only_covers(self):
self.identify = False
self.accept()
def start_download(gui, ids, callback):
d = ConfirmDialog(ids, gui)
ret = d.exec_()
d.b.clicked.disconnect()
if ret != d.Accepted:
return return
job = ThreadedJob('metadata bulk download', job = ThreadedJob('metadata bulk download',
_('Download metadata for %d books')%len(ids), _('Download metadata for %d books')%len(ids),
download, (ids, gui.current_db, identify, covers), {}, callback) download, (ids, gui.current_db, d.identify, d.covers), {}, callback)
gui.job_manager.run_threaded_job(job) gui.job_manager.run_threaded_job(job)
gui.status_bar.show_message(_('Metadata download started'), 3000) gui.status_bar.show_message(_('Metadata download started'), 3000)
# }}}
class ViewLog(QDialog): # {{{ class ViewLog(QDialog): # {{{
@ -93,9 +143,10 @@ def view_log(job, parent):
# }}} # }}}
# Apply downloaded metadata {{{
class ApplyDialog(QDialog): class ApplyDialog(QDialog):
def __init__(self, id_map, gui): def __init__(self, gui):
QDialog.__init__(self, gui) QDialog.__init__(self, gui)
self.l = l = QVBoxLayout() self.l = l = QVBoxLayout()
@ -104,27 +155,33 @@ class ApplyDialog(QDialog):
self.pb = QProgressBar(self) self.pb = QProgressBar(self)
l.addWidget(self.pb) l.addWidget(self.pb)
self.pb.setMinimum(0)
self.pb.setMaximum(len(id_map))
self.bb = QDialogButtonBox(QDialogButtonBox.Cancel) self.bb = QDialogButtonBox(QDialogButtonBox.Cancel)
self.bb.rejected.connect(self.reject) self.bb.rejected.connect(self.reject)
self.bb.accepted.connect(self.accept)
l.addWidget(self.bb) l.addWidget(self.bb)
self.gui = gui self.gui = gui
self.timer = QTimer(self)
self.timer.timeout.connect(self.do_one)
def start(self, id_map):
self.id_map = list(id_map.iteritems()) self.id_map = list(id_map.iteritems())
self.current_idx = 0 self.current_idx = 0
self.failures = [] self.failures = []
self.ids = [] self.ids = []
self.canceled = False self.canceled = False
self.pb.setMinimum(0)
QTimer.singleShot(20, self.do_one) self.pb.setMaximum(len(id_map))
self.timer.start(50)
def do_one(self): def do_one(self):
if self.canceled: if self.canceled:
return return
if self.current_idx >= len(self.id_map):
self.timer.stop()
self.finalize()
return
i, mi = self.id_map[self.current_idx] i, mi = self.id_map[self.current_idx]
db = self.gui.current_db db = self.gui.current_db
try: try:
@ -144,15 +201,11 @@ class ApplyDialog(QDialog):
pass pass
self.pb.setValue(self.pb.value()+1) self.pb.setValue(self.pb.value()+1)
if self.current_idx >= len(self.id_map) - 1:
self.finalize()
else:
self.current_idx += 1 self.current_idx += 1
QTimer.singleShot(20, self.do_one)
def reject(self): def reject(self):
self.canceled = True self.canceled = True
self.timer.stop()
QDialog.reject(self) QDialog.reject(self)
def finalize(self): def finalize(self):
@ -169,17 +222,18 @@ class ApplyDialog(QDialog):
title += ' - ' + authors_to_string(authors) title += ' - ' + authors_to_string(authors)
msg.append(title+'\n\n'+tb+'\n'+('*'*80)) msg.append(title+'\n\n'+tb+'\n'+('*'*80))
error_dialog(self, _('Some failures'), parent = self if self.isVisible() else self.parent()
error_dialog(parent, _('Some failures'),
_('Failed to apply updated metadata for some books' _('Failed to apply updated metadata for some books'
' in your library. Click "Show Details" to see ' ' in your library. Click "Show Details" to see '
'details.'), det_msg='\n\n'.join(msg), show=True) 'details.'), det_msg='\n\n'.join(msg), show=True)
self.accept()
if self.ids: if self.ids:
cr = self.gui.library_view.currentIndex().row() cr = self.gui.library_view.currentIndex().row()
self.gui.library_view.model().refresh_ids( self.gui.library_view.model().refresh_ids(
self.ids, cr) self.ids, cr)
if self.gui.cover_flow: if self.gui.cover_flow:
self.gui.cover_flow.dataChanged() self.gui.cover_flow.dataChanged()
self.accept()
_amd = None _amd = None
def apply_metadata(job, gui, q, result): def apply_metadata(job, gui, q, result):
@ -217,7 +271,10 @@ def apply_metadata(job, gui, q, result):
'Do you want to proceed?'), det_msg='\n'.join(modified)): 'Do you want to proceed?'), det_msg='\n'.join(modified)):
return return
_amd = ApplyDialog(id_map, gui) if _amd is None:
_amd = ApplyDialog(gui)
_amd.start(id_map)
if len(id_map) > 3:
_amd.exec_() _amd.exec_()
def proceed(gui, job): def proceed(gui, job):
@ -248,6 +305,8 @@ def proceed(gui, job):
q.show() q.show()
q.finished.connect(partial(apply_metadata, job, gui, q)) q.finished.connect(partial(apply_metadata, job, gui, q))
# }}}
def merge_result(oldmi, newmi): def merge_result(oldmi, newmi):
dummy = Metadata(_('Unknown')) dummy = Metadata(_('Unknown'))
for f in msprefs['ignore_fields']: for f in msprefs['ignore_fields']:

View File

@ -156,6 +156,9 @@ class MetadataSingleDialogBase(ResizableDialog):
self.identifiers = IdentifiersEdit(self) self.identifiers = IdentifiersEdit(self)
self.basic_metadata_widgets.append(self.identifiers) self.basic_metadata_widgets.append(self.identifiers)
self.clear_identifiers_button = QToolButton(self)
self.clear_identifiers_button.setIcon(QIcon(I('trash.png')))
self.clear_identifiers_button.clicked.connect(self.identifiers.clear)
self.publisher = PublisherEdit(self) self.publisher = PublisherEdit(self)
self.basic_metadata_widgets.append(self.publisher) self.basic_metadata_widgets.append(self.publisher)
@ -541,8 +544,8 @@ class MetadataSingleDialog(MetadataSingleDialogBase): # {{{
sto(self.rating, self.tags) sto(self.rating, self.tags)
create_row2(2, self.tags, self.tags_editor_button) create_row2(2, self.tags, self.tags_editor_button)
sto(self.tags_editor_button, self.identifiers) sto(self.tags_editor_button, self.identifiers)
create_row2(3, self.identifiers) create_row2(3, self.identifiers, self.clear_identifiers_button)
sto(self.identifiers, self.timestamp) sto(self.clear_identifiers_button, self.timestamp)
create_row2(4, self.timestamp, self.timestamp.clear_button) create_row2(4, self.timestamp, self.timestamp.clear_button)
sto(self.timestamp.clear_button, self.pubdate) sto(self.timestamp.clear_button, self.pubdate)
create_row2(5, self.pubdate, self.pubdate.clear_button) create_row2(5, self.pubdate, self.pubdate.clear_button)
@ -657,7 +660,8 @@ class MetadataSingleDialogAlt1(MetadataSingleDialogBase): # {{{
create_row(9, self.publisher, self.timestamp) create_row(9, self.publisher, self.timestamp)
create_row(10, self.timestamp, self.identifiers, create_row(10, self.timestamp, self.identifiers,
button=self.timestamp.clear_button, icon='trash.png') button=self.timestamp.clear_button, icon='trash.png')
create_row(11, self.identifiers, self.comments) create_row(11, self.identifiers, self.comments,
button=self.clear_identifiers_button, icon='trash.png')
tl.addItem(QSpacerItem(1, 1, QSizePolicy.Fixed, QSizePolicy.Expanding), tl.addItem(QSpacerItem(1, 1, QSizePolicy.Fixed, QSizePolicy.Expanding),
12, 1, 1 ,1) 12, 1, 1 ,1)

View File

@ -30,6 +30,7 @@ from calibre.ebooks.metadata.book.base import Metadata
from calibre.gui2 import error_dialog, NONE from calibre.gui2 import error_dialog, NONE
from calibre.utils.date import utcnow, fromordinal, format_date from calibre.utils.date import utcnow, fromordinal, format_date
from calibre.library.comments import comments_to_html from calibre.library.comments import comments_to_html
from calibre.constants import islinux
from calibre import force_unicode from calibre import force_unicode
# }}} # }}}
@ -116,6 +117,12 @@ class CoverDelegate(QStyledItemDelegate): # {{{
def paint(self, painter, option, index): def paint(self, painter, option, index):
QStyledItemDelegate.paint(self, painter, option, index) QStyledItemDelegate.paint(self, painter, option, index)
if islinux:
# On linux for some reason the selected color is drawn on top of
# the decoration
style = QApplication.style()
style.drawItemPixmap(painter, option.rect, Qt.AlignTop|Qt.AlignHCenter,
QPixmap(index.data(Qt.DecorationRole)))
if self.timer.isActive() and index.data(Qt.UserRole).toBool(): if self.timer.isActive() and index.data(Qt.UserRole).toBool():
rect = QRect(0, 0, self.spinner_width, self.spinner_width) rect = QRect(0, 0, self.spinner_width, self.spinner_width)
rect.moveCenter(option.rect.center()) rect.moveCenter(option.rect.center())
@ -945,7 +952,7 @@ class CoverFetch(QDialog): # {{{
# }}} # }}}
if __name__ == '__main__': if __name__ == '__main__':
#DEBUG_DIALOG = True DEBUG_DIALOG = True
app = QApplication([]) app = QApplication([])
d = FullFetch() d = FullFetch()
d.start(title='great gatsby', authors=['fitzgerald']) d.start(title='great gatsby', authors=['fitzgerald'])