diff --git a/resources/recipes/la_tribuna.recipe b/resources/recipes/la_tribuna.recipe index 739d11cc8d..c6d3f5cb28 100644 --- a/resources/recipes/la_tribuna.recipe +++ b/resources/recipes/la_tribuna.recipe @@ -2,24 +2,23 @@ __license__ = 'GPL v3' __author__ = 'Luis Hernandez' __copyright__ = 'Luis Hernandez' -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 class AdvancedUserRecipe1294946868(BasicNewsRecipe): - title = u'La Tribuna de Talavera' + title = u'La Tribuna de' publisher = u'Grupo PROMECAL' __author__ = 'Luis Hernández' - description = 'Diario local de Talavera de la Reina' - cover_url = 'http://www.latribunadetalavera.es/entorno/mancheta.gif' + description = 'Varios diarios locales del grupo PROMECAL' - oldest_article = 5 + oldest_article = 3 max_articles_per_feed = 50 remove_javascript = True @@ -27,7 +26,7 @@ class AdvancedUserRecipe1294946868(BasicNewsRecipe): use_embedded_content = False encoding = 'utf-8' - language = 'es' + language = 'es_ES' timefmt = '[%a, %d %b, %Y]' keep_only_tags = [ @@ -39,7 +38,20 @@ class AdvancedUserRecipe1294946868(BasicNewsRecipe): remove_tags_before = dict(name='div' , attrs={'class':['comparte']}) 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): for alink in soup.findAll('a'): @@ -48,4 +60,15 @@ class AdvancedUserRecipe1294946868(BasicNewsRecipe): alink.replaceWith(tstr) 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') + ] diff --git a/src/calibre/gui2/actions/edit_metadata.py b/src/calibre/gui2/actions/edit_metadata.py index 03fb8fa4eb..6c2cfb8126 100644 --- a/src/calibre/gui2/actions/edit_metadata.py +++ b/src/calibre/gui2/actions/edit_metadata.py @@ -160,7 +160,7 @@ class EditMetadataAction(InterfaceAction): break 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: break current_row += d.row_delta diff --git a/src/calibre/gui2/complete.py b/src/calibre/gui2/complete.py index 0ad8fb13d4..f589b30679 100644 --- a/src/calibre/gui2/complete.py +++ b/src/calibre/gui2/complete.py @@ -64,8 +64,6 @@ class CompleteWindow(QListView): # {{{ def do_selected(self, idx=None): 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(): data = unicode(self.model().data(idx, Qt.DisplayRole)) self.completion_selected.emit(data) @@ -81,6 +79,9 @@ class CompleteWindow(QListView): # {{{ self.hide() return True 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() return True 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 QLineEdit.eventFilter(self, o, e) + def hide_completion_window(self): + self.complete_window.hide() + def text_edited(self, *args): self.update_completions() diff --git a/src/calibre/gui2/convert/metadata.py b/src/calibre/gui2/convert/metadata.py index 23cac74cf8..81274f25a8 100644 --- a/src/calibre/gui2/convert/metadata.py +++ b/src/calibre/gui2/convert/metadata.py @@ -70,9 +70,6 @@ class MetadataWidget(Widget, Ui_Form): def initialize_metadata_options(self): self.initialize_combos() 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) self.title.setText(mi.title) @@ -109,6 +106,9 @@ class MetadataWidget(Widget, Ui_Form): def initalize_authors(self): all_authors = self.db.all_authors() 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: id, name = i @@ -124,6 +124,8 @@ class MetadataWidget(Widget, Ui_Form): def initialize_series(self): all_series = self.db.all_series() 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: id, name = i @@ -133,6 +135,8 @@ class MetadataWidget(Widget, Ui_Form): def initialize_publisher(self): all_publishers = self.db.all_publishers() 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: id, name = i diff --git a/src/calibre/gui2/convert/metadata.ui b/src/calibre/gui2/convert/metadata.ui index 61c27594c4..95ccac6890 100644 --- a/src/calibre/gui2/convert/metadata.ui +++ b/src/calibre/gui2/convert/metadata.ui @@ -190,7 +190,7 @@ - + Tags categorize the book. This is particularly useful while searching. <br><br>They can be any words or phrases, separated by commas. @@ -213,7 +213,7 @@ - + 10 @@ -248,14 +248,14 @@ - + true - + true @@ -277,19 +277,14 @@
widgets.h
- EnComboBox + MultiCompleteComboBox QComboBox -
widgets.h
+
calibre/gui2/complete.h
- CompleteComboBox - QComboBox -
widgets.h
-
- - CompleteLineEdit + MultiCompleteLineEdit QLineEdit -
widgets.h
+
calibre/gui2/complete.h
ImageView diff --git a/src/calibre/gui2/custom_column_widgets.py b/src/calibre/gui2/custom_column_widgets.py index 360a5bcd0a..5180999379 100644 --- a/src/calibre/gui2/custom_column_widgets.py +++ b/src/calibre/gui2/custom_column_widgets.py @@ -14,7 +14,7 @@ from PyQt4.Qt import QComboBox, QLabel, QSpinBox, QDoubleSpinBox, QDateEdit, \ QPushButton 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 import UNDEFINED_QDATE, error_dialog 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.sort(key=sort_key) if self.col_metadata['is_multiple']: - w = CompleteLineEdit(parent, values) + w = MultiCompleteLineEdit(parent) + w.update_items_cache(values) w.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred) else: - w = EnComboBox(parent) + w = MultiCompleteComboBox(parent) + w.set_separator(None) w.setSizeAdjustPolicy(w.AdjustToMinimumContentsLengthWithIcon) w.setMinimumContentsLength(25) 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) self.initial_val = val val = self.normalize_db_val(val) + self.widgets[1].update_items_cache(self.all_values) + if self.col_metadata['is_multiple']: self.setter(val) - self.widgets[1].update_items_cache(self.all_values) else: idx = None for i, c in enumerate(self.all_values): @@ -276,7 +279,7 @@ class Series(Base): def setup_ui(self, parent): values = self.all_values = list(self.db.all_custom(num=self.col_id)) values.sort(key=sort_key) - w = EnComboBox(parent) + w = MultiCompleteComboBox(parent) w.setSizeAdjustPolicy(w.AdjustToMinimumContentsLengthWithIcon) w.setMinimumContentsLength(25) self.name_widget = w @@ -305,6 +308,7 @@ class Series(Base): if c == val: idx = i self.name_widget.addItem(c) + self.name_widget.update_items_cache(self.all_values) self.name_widget.setEditText('') if idx is not None: self.widgets[1].setCurrentIndex(idx) @@ -670,7 +674,7 @@ class BulkDateTime(BulkBase): class BulkSeries(BulkBase): 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.sort(key=sort_key) self.main_widget.setSizeAdjustPolicy(self.main_widget.AdjustToMinimumContentsLengthWithIcon) @@ -705,6 +709,8 @@ class BulkSeries(BulkBase): def initialize(self, book_id): 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: self.main_widget.addItem(c) self.main_widget.setEditText('') @@ -795,7 +801,8 @@ class RemoveTags(QWidget): layout.setSpacing(5) 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) self.checkbox = QCheckBox(_('Remove all tags'), parent) 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.sort(key=sort_key) if self.col_metadata['is_multiple']: - self.make_widgets(parent, CompleteLineEdit, + self.make_widgets(parent, MultiCompleteLineEdit, extra_label_text=_('tags to add')) self.main_widget.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred) self.adding_widget = self.main_widget @@ -829,16 +836,16 @@ class BulkText(BulkBase): w.tags_box.textChanged.connect(self.a_c_checkbox_changed) w.checkbox.stateChanged.connect(self.a_c_checkbox_changed) else: - self.make_widgets(parent, EnComboBox) + self.make_widgets(parent, MultiCompleteComboBox) + self.main_widget.set_separator(None) self.main_widget.setSizeAdjustPolicy( self.main_widget.AdjustToMinimumContentsLengthWithIcon) self.main_widget.setMinimumContentsLength(25) self.ignore_change_signals = False def initialize(self, book_ids): - if self.col_metadata['is_multiple']: - self.main_widget.update_items_cache(self.all_values) - else: + self.main_widget.update_items_cache(self.all_values) + if not self.col_metadata['is_multiple']: val = self.get_initial_value(book_ids) self.initial_val = val = self.normalize_db_val(val) idx = None diff --git a/src/calibre/gui2/dialogs/add_empty_book.py b/src/calibre/gui2/dialogs/add_empty_book.py index b8339f95f5..9e5fb07308 100644 --- a/src/calibre/gui2/dialogs/add_empty_book.py +++ b/src/calibre/gui2/dialogs/add_empty_book.py @@ -7,8 +7,8 @@ __license__ = 'GPL v3' from PyQt4.Qt import QDialog, QGridLayout, QLabel, QDialogButtonBox, \ QApplication, QSpinBox, QToolButton, QIcon 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.gui2.complete import MultiCompleteComboBox class AddEmptyBookDialog(QDialog): @@ -32,7 +32,7 @@ class AddEmptyBookDialog(QDialog): self.author_label = QLabel(_('Set the author of the new books to:')) 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.AdjustToMinimumContentsLengthWithIcon) self.authors_combo.setEditable(True) diff --git a/src/calibre/gui2/dialogs/metadata_bulk.py b/src/calibre/gui2/dialogs/metadata_bulk.py index 533a344de5..12f49baaca 100644 --- a/src/calibre/gui2/dialogs/metadata_bulk.py +++ b/src/calibre/gui2/dialogs/metadata_bulk.py @@ -764,6 +764,8 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog): def initialize_series(self): all_series = self.db.all_series() 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: id, name = i @@ -773,6 +775,8 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog): def initialize_publisher(self): all_publishers = self.db.all_publishers() 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: id, name = i diff --git a/src/calibre/gui2/dialogs/metadata_bulk.ui b/src/calibre/gui2/dialogs/metadata_bulk.ui index b0f2c144fc..ecdb396662 100644 --- a/src/calibre/gui2/dialogs/metadata_bulk.ui +++ b/src/calibre/gui2/dialogs/metadata_bulk.ui @@ -76,7 +76,7 @@
- + true @@ -175,7 +175,7 @@ - + true @@ -195,7 +195,7 @@ - + Tags categorize the book. This is particularly useful while searching. <br><br>They can be any words or phrases, separated by commas. @@ -229,7 +229,7 @@ - + Comma separated list of tags to remove from the books. @@ -262,7 +262,7 @@ - + 0 @@ -1072,19 +1072,14 @@ not multiple and the destination field is multiple
widgets.h
- EnComboBox + MultiCompleteComboBox QComboBox -
widgets.h
+
calibre/gui2/complete.h
- CompleteComboBox - QComboBox -
widgets.h
-
- - CompleteLineEdit + MultiCompleteLineEdit QLineEdit -
widgets.h
+
calibre/gui2/complete.h
HistoryLineEdit diff --git a/src/calibre/gui2/dialogs/metadata_single.py b/src/calibre/gui2/dialogs/metadata_single.py index 43e26fad9d..0085d40c2d 100644 --- a/src/calibre/gui2/dialogs/metadata_single.py +++ b/src/calibre/gui2/dialogs/metadata_single.py @@ -740,6 +740,8 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): self.series.setSizeAdjustPolicy(self.series.AdjustToContentsOnFirstShow) all_series = self.db.all_series() 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) idx, c = None, 0 for i in all_series: @@ -757,6 +759,8 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): def initialize_publisher(self): all_publishers = self.db.all_publishers() 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) idx, c = None, 0 for i in all_publishers: diff --git a/src/calibre/gui2/dialogs/metadata_single.ui b/src/calibre/gui2/dialogs/metadata_single.ui index 23efc45399..5bcf268aaa 100644 --- a/src/calibre/gui2/dialogs/metadata_single.ui +++ b/src/calibre/gui2/dialogs/metadata_single.ui @@ -240,7 +240,7 @@ Using this button to create author sort will change author sort from red to gree
- + true @@ -313,7 +313,7 @@ If the box is colored green, then text matches the individual author's sort stri - + true @@ -335,7 +335,7 @@ If the box is colored green, then text matches the individual author's sort stri - + Tags categorize the book. This is particularly useful while searching. <br><br>They can be any words or phrases, separated by commas. @@ -379,7 +379,7 @@ If the box is colored green, then text matches the individual author's sort stri 5 - + List of known series. You can add new series. @@ -837,19 +837,14 @@ If the box is colored green, then text matches the individual author's sort stri
widgets.h
- EnComboBox - QComboBox -
widgets.h
-
- - CompleteLineEdit + MultiCompleteLineEdit QLineEdit -
widgets.h
+
calibre/gui2/complete.h
- CompleteComboBox + MultiCompleteComboBox QComboBox -
widgets.h
+
calibre/gui2/complete.h
FormatList diff --git a/src/calibre/gui2/dialogs/search.py b/src/calibre/gui2/dialogs/search.py index ab3fd3ec4e..9c91446f3c 100644 --- a/src/calibre/gui2/dialogs/search.py +++ b/src/calibre/gui2/dialogs/search.py @@ -3,7 +3,7 @@ __copyright__ = '2008, Kovid Goyal ' 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.library.caches import CONTAINS_MATCH, EQUALS_MATCH @@ -29,20 +29,18 @@ class SearchDialog(QDialog, Ui_Dialog): name = name.strip().replace('|', ',') self.authors_box.addItem(name) 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_space_before_sep(True) self.authors_box.update_items_cache(db.all_author_names()) all_series = db.all_series() 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: id, name = i self.series_box.addItem(name) self.series_box.setEditText('') - self.series_box.completer().setCompletionMode(QCompleter.PopupCompletion) - self.series_box.setAutoCompletionCaseSensitivity(Qt.CaseInsensitive) all_tags = db.all_tags() self.tags_box.update_items_cache(all_tags) diff --git a/src/calibre/gui2/dialogs/search.ui b/src/calibre/gui2/dialogs/search.ui index 1d013a1e9f..eb6fffdb60 100644 --- a/src/calibre/gui2/dialogs/search.ui +++ b/src/calibre/gui2/dialogs/search.ui @@ -265,21 +265,21 @@
- + Enter an author's name. Only one author can be used. - + Enter a series name, without an index. Only one series name can be used. - + Enter tags separated by spaces @@ -355,19 +355,14 @@
widgets.h
- EnComboBox - QComboBox -
widgets.h
-
- - CompleteLineEdit + MultiCompleteLineEdit QLineEdit -
widgets.h
+
calibre/gui2/complete.h
- CompleteComboBox + MultiCompleteComboBox QComboBox -
widgets.h
+
calibre/gui2/complete.h
diff --git a/src/calibre/gui2/metadata/basic_widgets.py b/src/calibre/gui2/metadata/basic_widgets.py index 6b89e306e6..d9c450807a 100644 --- a/src/calibre/gui2/metadata/basic_widgets.py +++ b/src/calibre/gui2/metadata/basic_widgets.py @@ -156,6 +156,7 @@ class AuthorsEdit(MultiCompleteComboBox): def __init__(self, parent): self.dialog = parent + self.books_to_refresh = set([]) MultiCompleteComboBox.__init__(self, parent) self.setToolTip(self.TOOLTIP) self.setWhatsThis(self.TOOLTIP) @@ -166,6 +167,7 @@ class AuthorsEdit(MultiCompleteComboBox): return _('Unknown') def initialize(self, db, id_): + self.books_to_refresh = set([]) all_authors = db.all_authors() all_authors.sort(key=lambda x : sort_key(x[1])) for i in all_authors: @@ -185,7 +187,8 @@ class AuthorsEdit(MultiCompleteComboBox): def commit(self, db, id_): 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 @dynamic_property @@ -824,6 +827,7 @@ class TagsEdit(MultiCompleteLineEdit): # {{{ def __init__(self, parent): MultiCompleteLineEdit.__init__(self, parent) + self.books_to_refresh = set([]) self.setToolTip(self.TOOLTIP) self.setWhatsThis(self.TOOLTIP) @@ -838,6 +842,7 @@ class TagsEdit(MultiCompleteLineEdit): # {{{ return property(fget=fget, fset=fset) def initialize(self, db, id_): + self.books_to_refresh = set([]) tags = db.tags(id_, index_is_id=True) tags = tags.split(',') if tags else [] self.current_val = tags @@ -866,7 +871,9 @@ class TagsEdit(MultiCompleteLineEdit): # {{{ 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 # }}} diff --git a/src/calibre/gui2/metadata/single.py b/src/calibre/gui2/metadata/single.py index 3b163d84f7..e5de2e3d97 100644 --- a/src/calibre/gui2/metadata/single.py +++ b/src/calibre/gui2/metadata/single.py @@ -31,6 +31,8 @@ class MetadataSingleDialogBase(ResizableDialog): def __init__(self, db, parent=None): self.db = db self.changed = set([]) + self.books_to_refresh = set([]) + self.rows_to_refresh = set([]) ResizableDialog.__init__(self, parent) def setupUi(self, *args): # {{{ @@ -192,6 +194,7 @@ class MetadataSingleDialogBase(ResizableDialog): def __call__(self, id_): self.book_id = id_ + self.books_to_refresh = set([]) for widget in self.basic_metadata_widgets: widget.initialize(self.db, id_) for widget in self.custom_metadata_widgets: @@ -295,6 +298,8 @@ class MetadataSingleDialogBase(ResizableDialog): try: if not widget.commit(self.db, self.book_id): return False + self.books_to_refresh |= getattr(widget, 'books_to_refresh', + set([])) except IOError, err: if err.errno == 13: # Permission denied import traceback @@ -309,6 +314,10 @@ class MetadataSingleDialogBase(ResizableDialog): widget.commit(self.book_id) self.db.commit() + rows = self.db.refresh_ids(list(self.books_to_refresh)) + if rows: + self.rows_to_refresh |= set(rows) + return True def accept(self): @@ -330,12 +339,14 @@ class MetadataSingleDialogBase(ResizableDialog): self.current_row = current_row if view_slot is not None: self.view_format.connect(view_slot) - self.do_one() + self.do_one(apply_changes=False) ret = self.exec_() self.break_cycles() 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 prev = next_ = None if self.current_row > 0: @@ -353,6 +364,7 @@ class MetadataSingleDialogBase(ResizableDialog): self.prev_button.setVisible(prev is not None) self(self.db.id(self.row_list[self.current_row])) + def break_cycles(self): # Break any reference cycles that could prevent python # 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): d = MetadataSingleDialog(db, parent) d.start(row_list, current_row, view_slot=view_slot) - return d.changed + return d.changed, d.rows_to_refresh if __name__ == '__main__': from PyQt4.Qt import QApplication diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index ce2d24c045..95e568bdbe 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -2153,6 +2153,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): tags = self.cleanup_tags(tags) books_to_refresh = set() for tag in (set(tags)-otags): + case_changed = False tag = tag.strip() if not tag: continue @@ -2170,8 +2171,6 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): if allow_case_change and etag != tag: self.conn.execute('UPDATE tags SET name=? WHERE id=?', (tag, tid)) case_changed = True - else: - case_changed = False else: tid = self.conn.execute('INSERT INTO tags(name) VALUES(?)', (tag,)).lastrowid