mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Merge from trunk
This commit is contained in:
commit
38b418de1b
@ -2,24 +2,23 @@
|
|||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__author__ = 'Luis Hernandez'
|
__author__ = 'Luis Hernandez'
|
||||||
__copyright__ = 'Luis Hernandez<tolyluis@gmail.com>'
|
__copyright__ = 'Luis Hernandez<tolyluis@gmail.com>'
|
||||||
description = 'Diario local de Talavera de la Reina - v1.2 - 27 Jan 2011'
|
__version__ = 'v1.0'
|
||||||
|
__date__ = '01 Feb 2011'
|
||||||
|
|
||||||
'''
|
'''
|
||||||
http://www.latribunadetalavera.es/
|
http://www.promecal.es/
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
class AdvancedUserRecipe1294946868(BasicNewsRecipe):
|
class AdvancedUserRecipe1294946868(BasicNewsRecipe):
|
||||||
|
|
||||||
title = u'La Tribuna de Talavera'
|
title = u'La Tribuna de'
|
||||||
publisher = u'Grupo PROMECAL'
|
publisher = u'Grupo PROMECAL'
|
||||||
|
|
||||||
__author__ = 'Luis Hernández'
|
__author__ = 'Luis Hernández'
|
||||||
description = 'Diario local de Talavera de la Reina'
|
description = 'Varios diarios locales del grupo PROMECAL'
|
||||||
cover_url = 'http://www.latribunadetalavera.es/entorno/mancheta.gif'
|
|
||||||
|
|
||||||
oldest_article = 5
|
oldest_article = 3
|
||||||
max_articles_per_feed = 50
|
max_articles_per_feed = 50
|
||||||
|
|
||||||
remove_javascript = True
|
remove_javascript = True
|
||||||
@ -27,7 +26,7 @@ class AdvancedUserRecipe1294946868(BasicNewsRecipe):
|
|||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
|
|
||||||
encoding = 'utf-8'
|
encoding = 'utf-8'
|
||||||
language = 'es'
|
language = 'es_ES'
|
||||||
timefmt = '[%a, %d %b, %Y]'
|
timefmt = '[%a, %d %b, %Y]'
|
||||||
|
|
||||||
keep_only_tags = [
|
keep_only_tags = [
|
||||||
@ -39,7 +38,20 @@ class AdvancedUserRecipe1294946868(BasicNewsRecipe):
|
|||||||
remove_tags_before = dict(name='div' , attrs={'class':['comparte']})
|
remove_tags_before = dict(name='div' , attrs={'class':['comparte']})
|
||||||
remove_tags_after = dict(name='div' , attrs={'id':['relacionadas']})
|
remove_tags_after = dict(name='div' , attrs={'id':['relacionadas']})
|
||||||
|
|
||||||
extra_css = ' p{text-align: justify; font-size: 100%} body{ text-align: left; font-family: serif; font-size: 100% } h1{ font-family: sans-serif; font-size:150%; font-weight: 700; text-align: justify; } h2{ font-family: sans-serif; font-size:120%; font-weight: 600; text-align: justify } h3{ font-family: sans-serif; font-size:60%; font-weight: 600; text-align: left } h4{ font-family: sans-serif; font-size:80%; font-weight: 600; text-align: left } h5{ font-family: sans-serif; font-size:70%; font-weight: 600; text-align: left }img{margin-bottom: 0.4em} '
|
remove_tags = [
|
||||||
|
dict(name='div', attrs={'id':['relacionadas']})
|
||||||
|
,dict(name='h3')
|
||||||
|
,dict(name='h5')
|
||||||
|
]
|
||||||
|
|
||||||
|
extra_css = """
|
||||||
|
p{text-align: justify; font-size: 100%}
|
||||||
|
body{text-align: left; font-family: serif; font-size: 100%}
|
||||||
|
h1{font-family: sans; font-size:150%; font-weight: bold; text-align: justify;}
|
||||||
|
h2{font-family: sans-serif; font-size:85%; font-style: italic; text-align: justify;}
|
||||||
|
h4{font-family: sans; font-size:75%; font-weight: bold; text-align: center;}
|
||||||
|
img{margin-bottom: 0.4em}
|
||||||
|
"""
|
||||||
|
|
||||||
def preprocess_html(self, soup):
|
def preprocess_html(self, soup):
|
||||||
for alink in soup.findAll('a'):
|
for alink in soup.findAll('a'):
|
||||||
@ -48,4 +60,15 @@ class AdvancedUserRecipe1294946868(BasicNewsRecipe):
|
|||||||
alink.replaceWith(tstr)
|
alink.replaceWith(tstr)
|
||||||
return soup
|
return soup
|
||||||
|
|
||||||
feeds = [(u'Portada', u'http://www.latribunadetalavera.es/rss.html')]
|
|
||||||
|
feeds = [
|
||||||
|
(u'Albacete', u'http://www.latribunadealbacete.es/rss.html')
|
||||||
|
,(u'Avila', u'http://www.diariodeavila.es/rss.html')
|
||||||
|
,(u'Burgos', u'http://www.diariodeburgos.es/rss.html')
|
||||||
|
,(u'Ciudad Real', u'http://www.latribunadeciudadreal.es/rss.html')
|
||||||
|
,(u'Palencia', u'http://www.diariopalentino.es/rss.html')
|
||||||
|
,(u'Puertollano', u'http://www.latribunadepuertollano.es/rss.html')
|
||||||
|
,(u'Talavera de la Reina', u'http://www.latribunadetalavera.es/rss.html')
|
||||||
|
,(u'Toledo', u'http://www.latribunadetoledo.es/rss.html')
|
||||||
|
,(u'Valladolid', u'http://www.eldiadevalladolid.com/rss.html')
|
||||||
|
]
|
||||||
|
@ -160,7 +160,7 @@ class EditMetadataAction(InterfaceAction):
|
|||||||
break
|
break
|
||||||
|
|
||||||
changed.add(d.id)
|
changed.add(d.id)
|
||||||
changed |= d.books_to_refresh
|
self.gui.library_view.model().refresh_ids(list(d.books_to_refresh))
|
||||||
if d.row_delta == 0:
|
if d.row_delta == 0:
|
||||||
break
|
break
|
||||||
current_row += d.row_delta
|
current_row += d.row_delta
|
||||||
|
@ -64,8 +64,6 @@ class CompleteWindow(QListView): # {{{
|
|||||||
|
|
||||||
def do_selected(self, idx=None):
|
def do_selected(self, idx=None):
|
||||||
idx = self.currentIndex() if idx is None else idx
|
idx = self.currentIndex() if idx is None else idx
|
||||||
#if not idx.isValid() and self.model().rowCount() > 0:
|
|
||||||
# idx = self.model().index(0)
|
|
||||||
if idx.isValid():
|
if idx.isValid():
|
||||||
data = unicode(self.model().data(idx, Qt.DisplayRole))
|
data = unicode(self.model().data(idx, Qt.DisplayRole))
|
||||||
self.completion_selected.emit(data)
|
self.completion_selected.emit(data)
|
||||||
@ -81,6 +79,9 @@ class CompleteWindow(QListView): # {{{
|
|||||||
self.hide()
|
self.hide()
|
||||||
return True
|
return True
|
||||||
elif key in (Qt.Key_Enter, Qt.Key_Return, Qt.Key_Tab):
|
elif key in (Qt.Key_Enter, Qt.Key_Return, Qt.Key_Tab):
|
||||||
|
if key == Qt.Key_Tab and not self.currentIndex().isValid():
|
||||||
|
if self.model().rowCount() > 0:
|
||||||
|
self.setCurrentIndex(self.model().index(0))
|
||||||
self.do_selected()
|
self.do_selected()
|
||||||
return True
|
return True
|
||||||
elif key in (Qt.Key_Up, Qt.Key_Down, Qt.Key_PageUp,
|
elif key in (Qt.Key_Up, Qt.Key_Down, Qt.Key_PageUp,
|
||||||
@ -197,6 +198,9 @@ class MultiCompleteLineEdit(QLineEdit):
|
|||||||
return True # Filter this event since the cw is visible
|
return True # Filter this event since the cw is visible
|
||||||
return QLineEdit.eventFilter(self, o, e)
|
return QLineEdit.eventFilter(self, o, e)
|
||||||
|
|
||||||
|
def hide_completion_window(self):
|
||||||
|
self.complete_window.hide()
|
||||||
|
|
||||||
|
|
||||||
def text_edited(self, *args):
|
def text_edited(self, *args):
|
||||||
self.update_completions()
|
self.update_completions()
|
||||||
|
@ -70,9 +70,6 @@ class MetadataWidget(Widget, Ui_Form):
|
|||||||
def initialize_metadata_options(self):
|
def initialize_metadata_options(self):
|
||||||
self.initialize_combos()
|
self.initialize_combos()
|
||||||
self.author.editTextChanged.connect(self.deduce_author_sort)
|
self.author.editTextChanged.connect(self.deduce_author_sort)
|
||||||
self.author.set_separator('&')
|
|
||||||
self.author.set_space_before_sep(True)
|
|
||||||
self.author.update_items_cache(self.db.all_author_names())
|
|
||||||
|
|
||||||
mi = self.db.get_metadata(self.book_id, index_is_id=True)
|
mi = self.db.get_metadata(self.book_id, index_is_id=True)
|
||||||
self.title.setText(mi.title)
|
self.title.setText(mi.title)
|
||||||
@ -109,6 +106,9 @@ class MetadataWidget(Widget, Ui_Form):
|
|||||||
def initalize_authors(self):
|
def initalize_authors(self):
|
||||||
all_authors = self.db.all_authors()
|
all_authors = self.db.all_authors()
|
||||||
all_authors.sort(key=lambda x : sort_key(x[1]))
|
all_authors.sort(key=lambda x : sort_key(x[1]))
|
||||||
|
self.author.set_separator('&')
|
||||||
|
self.author.set_space_before_sep(True)
|
||||||
|
self.author.update_items_cache(self.db.all_author_names())
|
||||||
|
|
||||||
for i in all_authors:
|
for i in all_authors:
|
||||||
id, name = i
|
id, name = i
|
||||||
@ -124,6 +124,8 @@ class MetadataWidget(Widget, Ui_Form):
|
|||||||
def initialize_series(self):
|
def initialize_series(self):
|
||||||
all_series = self.db.all_series()
|
all_series = self.db.all_series()
|
||||||
all_series.sort(key=lambda x : sort_key(x[1]))
|
all_series.sort(key=lambda x : sort_key(x[1]))
|
||||||
|
self.series.set_separator(None)
|
||||||
|
self.series.update_items_cache([x[1] for x in all_series])
|
||||||
|
|
||||||
for i in all_series:
|
for i in all_series:
|
||||||
id, name = i
|
id, name = i
|
||||||
@ -133,6 +135,8 @@ class MetadataWidget(Widget, Ui_Form):
|
|||||||
def initialize_publisher(self):
|
def initialize_publisher(self):
|
||||||
all_publishers = self.db.all_publishers()
|
all_publishers = self.db.all_publishers()
|
||||||
all_publishers.sort(key=lambda x : sort_key(x[1]))
|
all_publishers.sort(key=lambda x : sort_key(x[1]))
|
||||||
|
self.publisher.set_separator(None)
|
||||||
|
self.publisher.update_items_cache([x[1] for x in all_publishers])
|
||||||
|
|
||||||
for i in all_publishers:
|
for i in all_publishers:
|
||||||
id, name = i
|
id, name = i
|
||||||
|
@ -190,7 +190,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="1">
|
<item row="4" column="1">
|
||||||
<widget class="CompleteLineEdit" name="tags">
|
<widget class="MultiCompleteLineEdit" name="tags">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Tags categorize the book. This is particularly useful while searching. <br><br>They can be any words or phrases, separated by commas.</string>
|
<string>Tags categorize the book. This is particularly useful while searching. <br><br>They can be any words or phrases, separated by commas.</string>
|
||||||
</property>
|
</property>
|
||||||
@ -213,7 +213,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="1">
|
<item row="5" column="1">
|
||||||
<widget class="EnComboBox" name="series">
|
<widget class="MultiCompleteComboBox" name="series">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
<horstretch>10</horstretch>
|
<horstretch>10</horstretch>
|
||||||
@ -248,14 +248,14 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
<item row="3" column="1">
|
||||||
<widget class="EnComboBox" name="publisher">
|
<widget class="MultiCompleteComboBox" name="publisher">
|
||||||
<property name="editable">
|
<property name="editable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="CompleteComboBox" name="author">
|
<widget class="MultiCompleteComboBox" name="author">
|
||||||
<property name="editable">
|
<property name="editable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
@ -277,19 +277,14 @@
|
|||||||
<header>widgets.h</header>
|
<header>widgets.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>EnComboBox</class>
|
<class>MultiCompleteComboBox</class>
|
||||||
<extends>QComboBox</extends>
|
<extends>QComboBox</extends>
|
||||||
<header>widgets.h</header>
|
<header>calibre/gui2/complete.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>CompleteComboBox</class>
|
<class>MultiCompleteLineEdit</class>
|
||||||
<extends>QComboBox</extends>
|
|
||||||
<header>widgets.h</header>
|
|
||||||
</customwidget>
|
|
||||||
<customwidget>
|
|
||||||
<class>CompleteLineEdit</class>
|
|
||||||
<extends>QLineEdit</extends>
|
<extends>QLineEdit</extends>
|
||||||
<header>widgets.h</header>
|
<header>calibre/gui2/complete.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>ImageView</class>
|
<class>ImageView</class>
|
||||||
|
@ -14,7 +14,7 @@ from PyQt4.Qt import QComboBox, QLabel, QSpinBox, QDoubleSpinBox, QDateEdit, \
|
|||||||
QPushButton
|
QPushButton
|
||||||
|
|
||||||
from calibre.utils.date import qt_to_dt, now
|
from calibre.utils.date import qt_to_dt, now
|
||||||
from calibre.gui2.widgets import CompleteLineEdit, EnComboBox
|
from calibre.gui2.complete import MultiCompleteLineEdit, MultiCompleteComboBox
|
||||||
from calibre.gui2.comments_editor import Editor as CommentsEditor
|
from calibre.gui2.comments_editor import Editor as CommentsEditor
|
||||||
from calibre.gui2 import UNDEFINED_QDATE, error_dialog
|
from calibre.gui2 import UNDEFINED_QDATE, error_dialog
|
||||||
from calibre.utils.config import tweaks
|
from calibre.utils.config import tweaks
|
||||||
@ -228,10 +228,12 @@ class Text(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)
|
||||||
if self.col_metadata['is_multiple']:
|
if self.col_metadata['is_multiple']:
|
||||||
w = CompleteLineEdit(parent, values)
|
w = MultiCompleteLineEdit(parent)
|
||||||
|
w.update_items_cache(values)
|
||||||
w.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
|
w.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
|
||||||
else:
|
else:
|
||||||
w = EnComboBox(parent)
|
w = MultiCompleteComboBox(parent)
|
||||||
|
w.set_separator(None)
|
||||||
w.setSizeAdjustPolicy(w.AdjustToMinimumContentsLengthWithIcon)
|
w.setSizeAdjustPolicy(w.AdjustToMinimumContentsLengthWithIcon)
|
||||||
w.setMinimumContentsLength(25)
|
w.setMinimumContentsLength(25)
|
||||||
self.widgets = [QLabel('&'+self.col_metadata['name']+':', parent), w]
|
self.widgets = [QLabel('&'+self.col_metadata['name']+':', parent), w]
|
||||||
@ -240,9 +242,10 @@ class Text(Base):
|
|||||||
val = self.db.get_custom(book_id, num=self.col_id, index_is_id=True)
|
val = self.db.get_custom(book_id, num=self.col_id, index_is_id=True)
|
||||||
self.initial_val = val
|
self.initial_val = val
|
||||||
val = self.normalize_db_val(val)
|
val = self.normalize_db_val(val)
|
||||||
|
self.widgets[1].update_items_cache(self.all_values)
|
||||||
|
|
||||||
if self.col_metadata['is_multiple']:
|
if self.col_metadata['is_multiple']:
|
||||||
self.setter(val)
|
self.setter(val)
|
||||||
self.widgets[1].update_items_cache(self.all_values)
|
|
||||||
else:
|
else:
|
||||||
idx = None
|
idx = None
|
||||||
for i, c in enumerate(self.all_values):
|
for i, c in enumerate(self.all_values):
|
||||||
@ -276,7 +279,7 @@ class Series(Base):
|
|||||||
def setup_ui(self, parent):
|
def setup_ui(self, parent):
|
||||||
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 = EnComboBox(parent)
|
w = MultiCompleteComboBox(parent)
|
||||||
w.setSizeAdjustPolicy(w.AdjustToMinimumContentsLengthWithIcon)
|
w.setSizeAdjustPolicy(w.AdjustToMinimumContentsLengthWithIcon)
|
||||||
w.setMinimumContentsLength(25)
|
w.setMinimumContentsLength(25)
|
||||||
self.name_widget = w
|
self.name_widget = w
|
||||||
@ -305,6 +308,7 @@ class Series(Base):
|
|||||||
if c == val:
|
if c == val:
|
||||||
idx = i
|
idx = i
|
||||||
self.name_widget.addItem(c)
|
self.name_widget.addItem(c)
|
||||||
|
self.name_widget.update_items_cache(self.all_values)
|
||||||
self.name_widget.setEditText('')
|
self.name_widget.setEditText('')
|
||||||
if idx is not None:
|
if idx is not None:
|
||||||
self.widgets[1].setCurrentIndex(idx)
|
self.widgets[1].setCurrentIndex(idx)
|
||||||
@ -670,7 +674,7 @@ class BulkDateTime(BulkBase):
|
|||||||
class BulkSeries(BulkBase):
|
class BulkSeries(BulkBase):
|
||||||
|
|
||||||
def setup_ui(self, parent):
|
def setup_ui(self, parent):
|
||||||
self.make_widgets(parent, EnComboBox)
|
self.make_widgets(parent, MultiCompleteComboBox)
|
||||||
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)
|
||||||
self.main_widget.setSizeAdjustPolicy(self.main_widget.AdjustToMinimumContentsLengthWithIcon)
|
self.main_widget.setSizeAdjustPolicy(self.main_widget.AdjustToMinimumContentsLengthWithIcon)
|
||||||
@ -705,6 +709,8 @@ class BulkSeries(BulkBase):
|
|||||||
|
|
||||||
def initialize(self, book_id):
|
def initialize(self, book_id):
|
||||||
self.idx_widget.setChecked(False)
|
self.idx_widget.setChecked(False)
|
||||||
|
self.main_widget.set_separator(None)
|
||||||
|
self.main_widget.update_items_cache(self.all_values)
|
||||||
for c in self.all_values:
|
for c in self.all_values:
|
||||||
self.main_widget.addItem(c)
|
self.main_widget.addItem(c)
|
||||||
self.main_widget.setEditText('')
|
self.main_widget.setEditText('')
|
||||||
@ -795,7 +801,8 @@ class RemoveTags(QWidget):
|
|||||||
layout.setSpacing(5)
|
layout.setSpacing(5)
|
||||||
layout.setContentsMargins(0, 0, 0, 0)
|
layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
|
||||||
self.tags_box = CompleteLineEdit(parent, values)
|
self.tags_box = MultiCompleteLineEdit(parent)
|
||||||
|
self.tags_box.update_items_cache(values)
|
||||||
layout.addWidget(self.tags_box, stretch=3)
|
layout.addWidget(self.tags_box, stretch=3)
|
||||||
self.checkbox = QCheckBox(_('Remove all tags'), parent)
|
self.checkbox = QCheckBox(_('Remove all tags'), parent)
|
||||||
layout.addWidget(self.checkbox)
|
layout.addWidget(self.checkbox)
|
||||||
@ -816,7 +823,7 @@ class BulkText(BulkBase):
|
|||||||
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)
|
||||||
if self.col_metadata['is_multiple']:
|
if self.col_metadata['is_multiple']:
|
||||||
self.make_widgets(parent, CompleteLineEdit,
|
self.make_widgets(parent, MultiCompleteLineEdit,
|
||||||
extra_label_text=_('tags to add'))
|
extra_label_text=_('tags to add'))
|
||||||
self.main_widget.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
|
self.main_widget.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
|
||||||
self.adding_widget = self.main_widget
|
self.adding_widget = self.main_widget
|
||||||
@ -829,16 +836,16 @@ class BulkText(BulkBase):
|
|||||||
w.tags_box.textChanged.connect(self.a_c_checkbox_changed)
|
w.tags_box.textChanged.connect(self.a_c_checkbox_changed)
|
||||||
w.checkbox.stateChanged.connect(self.a_c_checkbox_changed)
|
w.checkbox.stateChanged.connect(self.a_c_checkbox_changed)
|
||||||
else:
|
else:
|
||||||
self.make_widgets(parent, EnComboBox)
|
self.make_widgets(parent, MultiCompleteComboBox)
|
||||||
|
self.main_widget.set_separator(None)
|
||||||
self.main_widget.setSizeAdjustPolicy(
|
self.main_widget.setSizeAdjustPolicy(
|
||||||
self.main_widget.AdjustToMinimumContentsLengthWithIcon)
|
self.main_widget.AdjustToMinimumContentsLengthWithIcon)
|
||||||
self.main_widget.setMinimumContentsLength(25)
|
self.main_widget.setMinimumContentsLength(25)
|
||||||
self.ignore_change_signals = False
|
self.ignore_change_signals = False
|
||||||
|
|
||||||
def initialize(self, book_ids):
|
def initialize(self, book_ids):
|
||||||
if self.col_metadata['is_multiple']:
|
self.main_widget.update_items_cache(self.all_values)
|
||||||
self.main_widget.update_items_cache(self.all_values)
|
if not self.col_metadata['is_multiple']:
|
||||||
else:
|
|
||||||
val = self.get_initial_value(book_ids)
|
val = self.get_initial_value(book_ids)
|
||||||
self.initial_val = val = self.normalize_db_val(val)
|
self.initial_val = val = self.normalize_db_val(val)
|
||||||
idx = None
|
idx = None
|
||||||
|
@ -7,8 +7,8 @@ __license__ = 'GPL v3'
|
|||||||
from PyQt4.Qt import QDialog, QGridLayout, QLabel, QDialogButtonBox, \
|
from PyQt4.Qt import QDialog, QGridLayout, QLabel, QDialogButtonBox, \
|
||||||
QApplication, QSpinBox, QToolButton, QIcon
|
QApplication, QSpinBox, QToolButton, QIcon
|
||||||
from calibre.ebooks.metadata import authors_to_string, string_to_authors
|
from calibre.ebooks.metadata import authors_to_string, string_to_authors
|
||||||
from calibre.gui2.widgets import CompleteComboBox
|
|
||||||
from calibre.utils.icu import sort_key
|
from calibre.utils.icu import sort_key
|
||||||
|
from calibre.gui2.complete import MultiCompleteComboBox
|
||||||
|
|
||||||
class AddEmptyBookDialog(QDialog):
|
class AddEmptyBookDialog(QDialog):
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ class AddEmptyBookDialog(QDialog):
|
|||||||
self.author_label = QLabel(_('Set the author of the new books to:'))
|
self.author_label = QLabel(_('Set the author of the new books to:'))
|
||||||
self._layout.addWidget(self.author_label, 2, 0, 1, 2)
|
self._layout.addWidget(self.author_label, 2, 0, 1, 2)
|
||||||
|
|
||||||
self.authors_combo = CompleteComboBox(self)
|
self.authors_combo = MultiCompleteComboBox(self)
|
||||||
self.authors_combo.setSizeAdjustPolicy(
|
self.authors_combo.setSizeAdjustPolicy(
|
||||||
self.authors_combo.AdjustToMinimumContentsLengthWithIcon)
|
self.authors_combo.AdjustToMinimumContentsLengthWithIcon)
|
||||||
self.authors_combo.setEditable(True)
|
self.authors_combo.setEditable(True)
|
||||||
|
@ -764,6 +764,8 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog):
|
|||||||
def initialize_series(self):
|
def initialize_series(self):
|
||||||
all_series = self.db.all_series()
|
all_series = self.db.all_series()
|
||||||
all_series.sort(key=lambda x : sort_key(x[1]))
|
all_series.sort(key=lambda x : sort_key(x[1]))
|
||||||
|
self.series.set_separator(None)
|
||||||
|
self.series.update_items_cache([x[1] for x in all_series])
|
||||||
|
|
||||||
for i in all_series:
|
for i in all_series:
|
||||||
id, name = i
|
id, name = i
|
||||||
@ -773,6 +775,8 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog):
|
|||||||
def initialize_publisher(self):
|
def initialize_publisher(self):
|
||||||
all_publishers = self.db.all_publishers()
|
all_publishers = self.db.all_publishers()
|
||||||
all_publishers.sort(key=lambda x : sort_key(x[1]))
|
all_publishers.sort(key=lambda x : sort_key(x[1]))
|
||||||
|
self.publisher.set_separator(None)
|
||||||
|
self.publisher.update_items_cache([x[1] for x in all_publishers])
|
||||||
|
|
||||||
for i in all_publishers:
|
for i in all_publishers:
|
||||||
id, name = i
|
id, name = i
|
||||||
|
@ -76,7 +76,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="CompleteComboBox" name="authors">
|
<widget class="MultiCompleteComboBox" name="authors">
|
||||||
<property name="editable">
|
<property name="editable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
@ -175,7 +175,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="1">
|
<item row="4" column="1">
|
||||||
<widget class="EnComboBox" name="publisher">
|
<widget class="MultiCompleteComboBox" name="publisher">
|
||||||
<property name="editable">
|
<property name="editable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
@ -195,7 +195,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="1">
|
<item row="5" column="1">
|
||||||
<widget class="CompleteLineEdit" name="tags">
|
<widget class="MultiCompleteLineEdit" name="tags">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Tags categorize the book. This is particularly useful while searching. <br><br>They can be any words or phrases, separated by commas.</string>
|
<string>Tags categorize the book. This is particularly useful while searching. <br><br>They can be any words or phrases, separated by commas.</string>
|
||||||
</property>
|
</property>
|
||||||
@ -229,7 +229,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="1">
|
<item row="6" column="1">
|
||||||
<widget class="CompleteLineEdit" name="remove_tags">
|
<widget class="MultiCompleteLineEdit" name="remove_tags">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Comma separated list of tags to remove from the books. </string>
|
<string>Comma separated list of tags to remove from the books. </string>
|
||||||
</property>
|
</property>
|
||||||
@ -262,7 +262,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="1">
|
<item row="7" column="1">
|
||||||
<widget class="EnComboBox" name="series">
|
<widget class="MultiCompleteComboBox" name="series">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
@ -1072,19 +1072,14 @@ not multiple and the destination field is multiple</string>
|
|||||||
<header>widgets.h</header>
|
<header>widgets.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>EnComboBox</class>
|
<class>MultiCompleteComboBox</class>
|
||||||
<extends>QComboBox</extends>
|
<extends>QComboBox</extends>
|
||||||
<header>widgets.h</header>
|
<header>calibre/gui2/complete.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>CompleteComboBox</class>
|
<class>MultiCompleteLineEdit</class>
|
||||||
<extends>QComboBox</extends>
|
|
||||||
<header>widgets.h</header>
|
|
||||||
</customwidget>
|
|
||||||
<customwidget>
|
|
||||||
<class>CompleteLineEdit</class>
|
|
||||||
<extends>QLineEdit</extends>
|
<extends>QLineEdit</extends>
|
||||||
<header>widgets.h</header>
|
<header>calibre/gui2/complete.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>HistoryLineEdit</class>
|
<class>HistoryLineEdit</class>
|
||||||
|
@ -740,6 +740,8 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
|
|||||||
self.series.setSizeAdjustPolicy(self.series.AdjustToContentsOnFirstShow)
|
self.series.setSizeAdjustPolicy(self.series.AdjustToContentsOnFirstShow)
|
||||||
all_series = self.db.all_series()
|
all_series = self.db.all_series()
|
||||||
all_series.sort(key=lambda x : sort_key(x[1]))
|
all_series.sort(key=lambda x : sort_key(x[1]))
|
||||||
|
self.series.set_separator(None)
|
||||||
|
self.series.update_items_cache([x[1] for x in all_series])
|
||||||
series_id = self.db.series_id(self.row)
|
series_id = self.db.series_id(self.row)
|
||||||
idx, c = None, 0
|
idx, c = None, 0
|
||||||
for i in all_series:
|
for i in all_series:
|
||||||
@ -757,6 +759,8 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
|
|||||||
def initialize_publisher(self):
|
def initialize_publisher(self):
|
||||||
all_publishers = self.db.all_publishers()
|
all_publishers = self.db.all_publishers()
|
||||||
all_publishers.sort(key=lambda x : sort_key(x[1]))
|
all_publishers.sort(key=lambda x : sort_key(x[1]))
|
||||||
|
self.publisher.set_separator(None)
|
||||||
|
self.publisher.update_items_cache([x[1] for x in all_publishers])
|
||||||
publisher_id = self.db.publisher_id(self.row)
|
publisher_id = self.db.publisher_id(self.row)
|
||||||
idx, c = None, 0
|
idx, c = None, 0
|
||||||
for i in all_publishers:
|
for i in all_publishers:
|
||||||
|
@ -240,7 +240,7 @@ Using this button to create author sort will change author sort from red to gree
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="2" column="1">
|
||||||
<widget class="CompleteComboBox" name="authors">
|
<widget class="MultiCompleteComboBox" name="authors">
|
||||||
<property name="editable">
|
<property name="editable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
@ -313,7 +313,7 @@ If the box is colored green, then text matches the individual author's sort stri
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="1" colspan="2">
|
<item row="5" column="1" colspan="2">
|
||||||
<widget class="EnComboBox" name="publisher">
|
<widget class="MultiCompleteComboBox" name="publisher">
|
||||||
<property name="editable">
|
<property name="editable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
@ -335,7 +335,7 @@ If the box is colored green, then text matches the individual author's sort stri
|
|||||||
<item row="6" column="1">
|
<item row="6" column="1">
|
||||||
<layout class="QHBoxLayout" name="_2">
|
<layout class="QHBoxLayout" name="_2">
|
||||||
<item>
|
<item>
|
||||||
<widget class="CompleteLineEdit" name="tags">
|
<widget class="MultiCompleteLineEdit" name="tags">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Tags categorize the book. This is particularly useful while searching. <br><br>They can be any words or phrases, separated by commas.</string>
|
<string>Tags categorize the book. This is particularly useful while searching. <br><br>They can be any words or phrases, separated by commas.</string>
|
||||||
</property>
|
</property>
|
||||||
@ -379,7 +379,7 @@ If the box is colored green, then text matches the individual author's sort stri
|
|||||||
<number>5</number>
|
<number>5</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="EnComboBox" name="series">
|
<widget class="MultiCompleteComboBox" name="series">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>List of known series. You can add new series.</string>
|
<string>List of known series. You can add new series.</string>
|
||||||
</property>
|
</property>
|
||||||
@ -837,19 +837,14 @@ If the box is colored green, then text matches the individual author's sort stri
|
|||||||
<header>widgets.h</header>
|
<header>widgets.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>EnComboBox</class>
|
<class>MultiCompleteLineEdit</class>
|
||||||
<extends>QComboBox</extends>
|
|
||||||
<header>widgets.h</header>
|
|
||||||
</customwidget>
|
|
||||||
<customwidget>
|
|
||||||
<class>CompleteLineEdit</class>
|
|
||||||
<extends>QLineEdit</extends>
|
<extends>QLineEdit</extends>
|
||||||
<header>widgets.h</header>
|
<header>calibre/gui2/complete.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>CompleteComboBox</class>
|
<class>MultiCompleteComboBox</class>
|
||||||
<extends>QComboBox</extends>
|
<extends>QComboBox</extends>
|
||||||
<header>widgets.h</header>
|
<header>calibre/gui2/complete.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>FormatList</class>
|
<class>FormatList</class>
|
||||||
|
@ -3,7 +3,7 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
|||||||
|
|
||||||
import re, copy
|
import re, copy
|
||||||
|
|
||||||
from PyQt4.Qt import QDialog, QDialogButtonBox, QCompleter, Qt
|
from PyQt4.Qt import QDialog, QDialogButtonBox
|
||||||
|
|
||||||
from calibre.gui2.dialogs.search_ui import Ui_Dialog
|
from calibre.gui2.dialogs.search_ui import Ui_Dialog
|
||||||
from calibre.library.caches import CONTAINS_MATCH, EQUALS_MATCH
|
from calibre.library.caches import CONTAINS_MATCH, EQUALS_MATCH
|
||||||
@ -29,20 +29,18 @@ class SearchDialog(QDialog, Ui_Dialog):
|
|||||||
name = name.strip().replace('|', ',')
|
name = name.strip().replace('|', ',')
|
||||||
self.authors_box.addItem(name)
|
self.authors_box.addItem(name)
|
||||||
self.authors_box.setEditText('')
|
self.authors_box.setEditText('')
|
||||||
self.authors_box.completer().setCompletionMode(QCompleter.PopupCompletion)
|
|
||||||
self.authors_box.setAutoCompletionCaseSensitivity(Qt.CaseInsensitive)
|
|
||||||
self.authors_box.set_separator('&')
|
self.authors_box.set_separator('&')
|
||||||
self.authors_box.set_space_before_sep(True)
|
self.authors_box.set_space_before_sep(True)
|
||||||
self.authors_box.update_items_cache(db.all_author_names())
|
self.authors_box.update_items_cache(db.all_author_names())
|
||||||
|
|
||||||
all_series = db.all_series()
|
all_series = db.all_series()
|
||||||
all_series.sort(key=lambda x : sort_key(x[1]))
|
all_series.sort(key=lambda x : sort_key(x[1]))
|
||||||
|
self.series_box.set_separator(None)
|
||||||
|
self.series_box.update_items_cache([x[1] for x in all_series])
|
||||||
for i in all_series:
|
for i in all_series:
|
||||||
id, name = i
|
id, name = i
|
||||||
self.series_box.addItem(name)
|
self.series_box.addItem(name)
|
||||||
self.series_box.setEditText('')
|
self.series_box.setEditText('')
|
||||||
self.series_box.completer().setCompletionMode(QCompleter.PopupCompletion)
|
|
||||||
self.series_box.setAutoCompletionCaseSensitivity(Qt.CaseInsensitive)
|
|
||||||
|
|
||||||
all_tags = db.all_tags()
|
all_tags = db.all_tags()
|
||||||
self.tags_box.update_items_cache(all_tags)
|
self.tags_box.update_items_cache(all_tags)
|
||||||
|
@ -265,21 +265,21 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="2" column="1">
|
||||||
<widget class="CompleteComboBox" name="authors_box">
|
<widget class="MultiCompleteComboBox" name="authors_box">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Enter an author's name. Only one author can be used.</string>
|
<string>Enter an author's name. Only one author can be used.</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
<item row="3" column="1">
|
||||||
<widget class="EnComboBox" name="series_box">
|
<widget class="MultiCompleteComboBox" name="series_box">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Enter a series name, without an index. Only one series name can be used.</string>
|
<string>Enter a series name, without an index. Only one series name can be used.</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="1">
|
<item row="4" column="1">
|
||||||
<widget class="CompleteLineEdit" name="tags_box">
|
<widget class="MultiCompleteLineEdit" name="tags_box">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Enter tags separated by spaces</string>
|
<string>Enter tags separated by spaces</string>
|
||||||
</property>
|
</property>
|
||||||
@ -355,19 +355,14 @@
|
|||||||
<header>widgets.h</header>
|
<header>widgets.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>EnComboBox</class>
|
<class>MultiCompleteLineEdit</class>
|
||||||
<extends>QComboBox</extends>
|
|
||||||
<header>widgets.h</header>
|
|
||||||
</customwidget>
|
|
||||||
<customwidget>
|
|
||||||
<class>CompleteLineEdit</class>
|
|
||||||
<extends>QLineEdit</extends>
|
<extends>QLineEdit</extends>
|
||||||
<header>widgets.h</header>
|
<header>calibre/gui2/complete.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>CompleteComboBox</class>
|
<class>MultiCompleteComboBox</class>
|
||||||
<extends>QComboBox</extends>
|
<extends>QComboBox</extends>
|
||||||
<header>widgets.h</header>
|
<header>calibre/gui2/complete.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<tabstops>
|
<tabstops>
|
||||||
|
@ -156,6 +156,7 @@ class AuthorsEdit(MultiCompleteComboBox):
|
|||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
self.dialog = parent
|
self.dialog = parent
|
||||||
|
self.books_to_refresh = set([])
|
||||||
MultiCompleteComboBox.__init__(self, parent)
|
MultiCompleteComboBox.__init__(self, parent)
|
||||||
self.setToolTip(self.TOOLTIP)
|
self.setToolTip(self.TOOLTIP)
|
||||||
self.setWhatsThis(self.TOOLTIP)
|
self.setWhatsThis(self.TOOLTIP)
|
||||||
@ -166,6 +167,7 @@ class AuthorsEdit(MultiCompleteComboBox):
|
|||||||
return _('Unknown')
|
return _('Unknown')
|
||||||
|
|
||||||
def initialize(self, db, id_):
|
def initialize(self, db, id_):
|
||||||
|
self.books_to_refresh = set([])
|
||||||
all_authors = db.all_authors()
|
all_authors = db.all_authors()
|
||||||
all_authors.sort(key=lambda x : sort_key(x[1]))
|
all_authors.sort(key=lambda x : sort_key(x[1]))
|
||||||
for i in all_authors:
|
for i in all_authors:
|
||||||
@ -185,7 +187,8 @@ class AuthorsEdit(MultiCompleteComboBox):
|
|||||||
|
|
||||||
def commit(self, db, id_):
|
def commit(self, db, id_):
|
||||||
authors = self.current_val
|
authors = self.current_val
|
||||||
db.set_authors(id_, authors, notify=False)
|
self.books_to_refresh |= db.set_authors(id_, authors, notify=False,
|
||||||
|
allow_case_change=True)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@dynamic_property
|
@dynamic_property
|
||||||
@ -824,6 +827,7 @@ class TagsEdit(MultiCompleteLineEdit): # {{{
|
|||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
MultiCompleteLineEdit.__init__(self, parent)
|
MultiCompleteLineEdit.__init__(self, parent)
|
||||||
|
self.books_to_refresh = set([])
|
||||||
self.setToolTip(self.TOOLTIP)
|
self.setToolTip(self.TOOLTIP)
|
||||||
self.setWhatsThis(self.TOOLTIP)
|
self.setWhatsThis(self.TOOLTIP)
|
||||||
|
|
||||||
@ -838,6 +842,7 @@ class TagsEdit(MultiCompleteLineEdit): # {{{
|
|||||||
return property(fget=fget, fset=fset)
|
return property(fget=fget, fset=fset)
|
||||||
|
|
||||||
def initialize(self, db, id_):
|
def initialize(self, db, id_):
|
||||||
|
self.books_to_refresh = set([])
|
||||||
tags = db.tags(id_, index_is_id=True)
|
tags = db.tags(id_, index_is_id=True)
|
||||||
tags = tags.split(',') if tags else []
|
tags = tags.split(',') if tags else []
|
||||||
self.current_val = tags
|
self.current_val = tags
|
||||||
@ -866,7 +871,9 @@ class TagsEdit(MultiCompleteLineEdit): # {{{
|
|||||||
|
|
||||||
|
|
||||||
def commit(self, db, id_):
|
def commit(self, db, id_):
|
||||||
db.set_tags(id_, self.current_val, notify=False, commit=False)
|
self.books_to_refresh |= db.set_tags(
|
||||||
|
id_, self.current_val, notify=False, commit=False,
|
||||||
|
allow_case_change=True)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
@ -31,6 +31,8 @@ class MetadataSingleDialogBase(ResizableDialog):
|
|||||||
def __init__(self, db, parent=None):
|
def __init__(self, db, parent=None):
|
||||||
self.db = db
|
self.db = db
|
||||||
self.changed = set([])
|
self.changed = set([])
|
||||||
|
self.books_to_refresh = set([])
|
||||||
|
self.rows_to_refresh = set([])
|
||||||
ResizableDialog.__init__(self, parent)
|
ResizableDialog.__init__(self, parent)
|
||||||
|
|
||||||
def setupUi(self, *args): # {{{
|
def setupUi(self, *args): # {{{
|
||||||
@ -192,6 +194,7 @@ class MetadataSingleDialogBase(ResizableDialog):
|
|||||||
|
|
||||||
def __call__(self, id_):
|
def __call__(self, id_):
|
||||||
self.book_id = id_
|
self.book_id = id_
|
||||||
|
self.books_to_refresh = set([])
|
||||||
for widget in self.basic_metadata_widgets:
|
for widget in self.basic_metadata_widgets:
|
||||||
widget.initialize(self.db, id_)
|
widget.initialize(self.db, id_)
|
||||||
for widget in self.custom_metadata_widgets:
|
for widget in self.custom_metadata_widgets:
|
||||||
@ -295,6 +298,8 @@ class MetadataSingleDialogBase(ResizableDialog):
|
|||||||
try:
|
try:
|
||||||
if not widget.commit(self.db, self.book_id):
|
if not widget.commit(self.db, self.book_id):
|
||||||
return False
|
return False
|
||||||
|
self.books_to_refresh |= getattr(widget, 'books_to_refresh',
|
||||||
|
set([]))
|
||||||
except IOError, err:
|
except IOError, err:
|
||||||
if err.errno == 13: # Permission denied
|
if err.errno == 13: # Permission denied
|
||||||
import traceback
|
import traceback
|
||||||
@ -309,6 +314,10 @@ class MetadataSingleDialogBase(ResizableDialog):
|
|||||||
widget.commit(self.book_id)
|
widget.commit(self.book_id)
|
||||||
|
|
||||||
self.db.commit()
|
self.db.commit()
|
||||||
|
rows = self.db.refresh_ids(list(self.books_to_refresh))
|
||||||
|
if rows:
|
||||||
|
self.rows_to_refresh |= set(rows)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
@ -330,12 +339,14 @@ class MetadataSingleDialogBase(ResizableDialog):
|
|||||||
self.current_row = current_row
|
self.current_row = current_row
|
||||||
if view_slot is not None:
|
if view_slot is not None:
|
||||||
self.view_format.connect(view_slot)
|
self.view_format.connect(view_slot)
|
||||||
self.do_one()
|
self.do_one(apply_changes=False)
|
||||||
ret = self.exec_()
|
ret = self.exec_()
|
||||||
self.break_cycles()
|
self.break_cycles()
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def do_one(self, delta=0):
|
def do_one(self, delta=0, apply_changes=True):
|
||||||
|
if apply_changes:
|
||||||
|
self.apply_changes()
|
||||||
self.current_row += delta
|
self.current_row += delta
|
||||||
prev = next_ = None
|
prev = next_ = None
|
||||||
if self.current_row > 0:
|
if self.current_row > 0:
|
||||||
@ -353,6 +364,7 @@ class MetadataSingleDialogBase(ResizableDialog):
|
|||||||
self.prev_button.setVisible(prev is not None)
|
self.prev_button.setVisible(prev is not None)
|
||||||
self(self.db.id(self.row_list[self.current_row]))
|
self(self.db.id(self.row_list[self.current_row]))
|
||||||
|
|
||||||
|
|
||||||
def break_cycles(self):
|
def break_cycles(self):
|
||||||
# Break any reference cycles that could prevent python
|
# Break any reference cycles that could prevent python
|
||||||
# from garbage collecting this dialog
|
# from garbage collecting this dialog
|
||||||
@ -618,7 +630,7 @@ class MetadataSingleDialogAlt(MetadataSingleDialogBase): # {{{
|
|||||||
def edit_metadata(db, row_list, current_row, parent=None, view_slot=None):
|
def edit_metadata(db, row_list, current_row, parent=None, view_slot=None):
|
||||||
d = MetadataSingleDialog(db, parent)
|
d = MetadataSingleDialog(db, parent)
|
||||||
d.start(row_list, current_row, view_slot=view_slot)
|
d.start(row_list, current_row, view_slot=view_slot)
|
||||||
return d.changed
|
return d.changed, d.rows_to_refresh
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
from PyQt4.Qt import QApplication
|
from PyQt4.Qt import QApplication
|
||||||
|
@ -2153,6 +2153,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
tags = self.cleanup_tags(tags)
|
tags = self.cleanup_tags(tags)
|
||||||
books_to_refresh = set()
|
books_to_refresh = set()
|
||||||
for tag in (set(tags)-otags):
|
for tag in (set(tags)-otags):
|
||||||
|
case_changed = False
|
||||||
tag = tag.strip()
|
tag = tag.strip()
|
||||||
if not tag:
|
if not tag:
|
||||||
continue
|
continue
|
||||||
@ -2170,8 +2171,6 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
if allow_case_change and etag != tag:
|
if allow_case_change and etag != tag:
|
||||||
self.conn.execute('UPDATE tags SET name=? WHERE id=?', (tag, tid))
|
self.conn.execute('UPDATE tags SET name=? WHERE id=?', (tag, tid))
|
||||||
case_changed = True
|
case_changed = True
|
||||||
else:
|
|
||||||
case_changed = False
|
|
||||||
else:
|
else:
|
||||||
tid = self.conn.execute('INSERT INTO tags(name) VALUES(?)', (tag,)).lastrowid
|
tid = self.conn.execute('INSERT INTO tags(name) VALUES(?)', (tag,)).lastrowid
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user