mirror of
git://github.com/kovidgoyal/calibre.git
synced 2026-04-28 07:23:34 +02:00
Fix (I hope) crashes in MultiCompleteComboBox. Also the drop down arrow now only shows the items that start with whatever text is currently entered in the box
This commit is contained in:
parent
e6788b5814
commit
c8b5db5209
9 changed files with 41 additions and 149 deletions
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
|
||||
from PyQt4.Qt import (QLineEdit, QAbstractListModel, Qt,
|
||||
QApplication, QCompleter, pyqtSignal)
|
||||
QApplication, QCompleter)
|
||||
|
||||
from calibre.utils.icu import sort_key, lower
|
||||
from calibre.gui2 import NONE
|
||||
|
|
@ -56,7 +56,7 @@ class MultiCompleteLineEdit(QLineEdit, LineEditECM):
|
|||
to complete non multiple fields as well.
|
||||
'''
|
||||
|
||||
def __init__(self, parent=None):
|
||||
def __init__(self, parent=None, completer_widget=None):
|
||||
QLineEdit.__init__(self, parent)
|
||||
|
||||
self.sep = ','
|
||||
|
|
@ -66,7 +66,7 @@ def __init__(self, parent=None):
|
|||
|
||||
self._model = CompleteModel(parent=self)
|
||||
self._completer = c = QCompleter(self._model, self)
|
||||
c.setWidget(self)
|
||||
c.setWidget(self if completer_widget is None else completer_widget)
|
||||
c.setCompletionMode(QCompleter.PopupCompletion)
|
||||
c.setCaseSensitivity(Qt.CaseInsensitive)
|
||||
c.setModelSorting(self._model.sorting)
|
||||
|
|
@ -158,21 +158,13 @@ def fset(self, items):
|
|||
|
||||
class MultiCompleteComboBox(EnComboBox):
|
||||
|
||||
clear_edit_text = pyqtSignal()
|
||||
|
||||
def __init__(self, *args):
|
||||
EnComboBox.__init__(self, *args)
|
||||
self.setLineEdit(MultiCompleteLineEdit(self))
|
||||
# Needed to allow changing the case of an existing item
|
||||
# otherwise on focus out, the text is changed to the
|
||||
# item that matches case insensitively
|
||||
c = self.lineEdit().completer()
|
||||
c.setCaseSensitivity(Qt.CaseSensitive)
|
||||
self.dummy_model = CompleteModel(self)
|
||||
c.setModel(self.dummy_model)
|
||||
self.lineEdit()._completer.setWidget(self)
|
||||
self.clear_edit_text.connect(self.clearEditText,
|
||||
type=Qt.QueuedConnection)
|
||||
self.le = MultiCompleteLineEdit(self, completer_widget=self)
|
||||
self.setLineEdit(self.le)
|
||||
|
||||
def showPopup(self):
|
||||
self.le._completer.complete()
|
||||
|
||||
def update_items_cache(self, complete_items):
|
||||
self.lineEdit().update_items_cache(complete_items)
|
||||
|
|
@ -187,18 +179,10 @@ def set_add_separator(self, what):
|
|||
self.lineEdit().set_add_separator(what)
|
||||
|
||||
def show_initial_value(self, what):
|
||||
'''
|
||||
Show an initial value. Handle the case of the initial value being blank
|
||||
correctly (on Qt 4.8.0 having a blank value causes the first value from
|
||||
the completer to be shown, when the event loop runs).
|
||||
'''
|
||||
what = unicode(what)
|
||||
what = unicode(what) if what else u''
|
||||
le = self.lineEdit()
|
||||
if not what.strip():
|
||||
self.clear_edit_text.emit()
|
||||
else:
|
||||
self.setEditText(what)
|
||||
le.selectAll()
|
||||
self.setEditText(what)
|
||||
le.selectAll()
|
||||
|
||||
if __name__ == '__main__':
|
||||
from PyQt4.Qt import QDialog, QVBoxLayout
|
||||
|
|
@ -207,5 +191,8 @@ def show_initial_value(self, what):
|
|||
d.setLayout(QVBoxLayout())
|
||||
le = MultiCompleteComboBox(d)
|
||||
d.layout().addWidget(le)
|
||||
le.all_items = ['one', 'otwo', 'othree', 'ooone', 'ootwo', 'oothree']
|
||||
items = ['one', 'otwo', 'othree', 'ooone', 'ootwo',
|
||||
'oothree']
|
||||
le.update_items_cache(items)
|
||||
le.show_initial_value('')
|
||||
d.exec_()
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@
|
|||
|
||||
from calibre.gui2 import choose_images, error_dialog
|
||||
from calibre.gui2.convert.metadata_ui import Ui_Form
|
||||
from calibre.ebooks.metadata import (authors_to_string, string_to_authors,
|
||||
MetaInformation, title_sort)
|
||||
from calibre.ebooks.metadata import (string_to_authors, MetaInformation,
|
||||
title_sort)
|
||||
from calibre.ebooks.metadata.opf2 import metadata_to_opf
|
||||
from calibre.ptempfile import PersistentTemporaryFile
|
||||
from calibre.gui2.convert import Widget
|
||||
|
|
@ -74,14 +74,12 @@ def initialize_metadata_options(self):
|
|||
|
||||
mi = self.db.get_metadata(self.book_id, index_is_id=True)
|
||||
self.title.setText(mi.title)
|
||||
if mi.publisher:
|
||||
self.publisher.setCurrentIndex(self.publisher.findText(mi.publisher))
|
||||
self.publisher.show_initial_value(mi.publisher if mi.publisher else '')
|
||||
self.author_sort.setText(mi.author_sort if mi.author_sort else '')
|
||||
self.tags.setText(', '.join(mi.tags if mi.tags else []))
|
||||
self.tags.update_items_cache(self.db.all_tags())
|
||||
self.comment.html = comments_to_html(mi.comments) if mi.comments else ''
|
||||
if mi.series:
|
||||
self.series.setCurrentIndex(self.series.findText(mi.series))
|
||||
self.series.show_initial_value(mi.series if mi.series else '')
|
||||
if mi.series_index is not None:
|
||||
try:
|
||||
self.series_index.setValue(mi.series_index)
|
||||
|
|
@ -118,16 +116,11 @@ def initalize_authors(self):
|
|||
self.author.set_add_separator(tweaks['authors_completer_append_separator'])
|
||||
self.author.update_items_cache(self.db.all_author_names())
|
||||
|
||||
for i in all_authors:
|
||||
id, name = i
|
||||
name = authors_to_string([name.strip().replace('|', ',') for n in name.split(',')])
|
||||
self.author.addItem(name)
|
||||
|
||||
au = self.db.authors(self.book_id, True)
|
||||
if not au:
|
||||
au = _('Unknown')
|
||||
au = ' & '.join([a.strip().replace('|', ',') for a in au.split(',')])
|
||||
self.author.setEditText(au)
|
||||
self.author.show_initial_value(au)
|
||||
|
||||
def initialize_series(self):
|
||||
all_series = self.db.all_series()
|
||||
|
|
@ -135,22 +128,12 @@ def initialize_series(self):
|
|||
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
|
||||
self.series.addItem(name)
|
||||
self.series.setCurrentIndex(-1)
|
||||
|
||||
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
|
||||
self.publisher.addItem(name)
|
||||
self.publisher.setCurrentIndex(-1)
|
||||
|
||||
def get_title_and_authors(self):
|
||||
title = unicode(self.title.text()).strip()
|
||||
if not title:
|
||||
|
|
@ -179,6 +162,7 @@ def get_metadata(self):
|
|||
if tags:
|
||||
mi.tags = tags
|
||||
|
||||
print (mi)
|
||||
return mi
|
||||
|
||||
def select_cover(self):
|
||||
|
|
|
|||
|
|
@ -314,14 +314,7 @@ def initialize(self, book_id):
|
|||
if self.col_metadata['is_multiple']:
|
||||
self.setter(val)
|
||||
else:
|
||||
idx = None
|
||||
for i, c in enumerate(values):
|
||||
if c == val:
|
||||
idx = i
|
||||
self.widgets[1].addItem(c)
|
||||
self.widgets[1].setEditText('')
|
||||
if idx is not None:
|
||||
self.widgets[1].setCurrentIndex(idx)
|
||||
self.widgets[1].show_initial_value(val)
|
||||
|
||||
def setter(self, val):
|
||||
if self.col_metadata['is_multiple']:
|
||||
|
|
@ -396,16 +389,8 @@ def initialize(self, book_id):
|
|||
self.initial_index = s_index
|
||||
self.initial_val = val
|
||||
val = self.normalize_db_val(val)
|
||||
idx = None
|
||||
self.name_widget.clear()
|
||||
for i, c in enumerate(values):
|
||||
if c == val:
|
||||
idx = i
|
||||
self.name_widget.addItem(c)
|
||||
self.name_widget.update_items_cache(values)
|
||||
self.name_widget.setEditText('')
|
||||
if idx is not None:
|
||||
self.widgets[1].setCurrentIndex(idx)
|
||||
self.name_widget.show_initial_value(val)
|
||||
|
||||
def getter(self):
|
||||
n = unicode(self.name_widget.currentText()).strip()
|
||||
|
|
@ -860,8 +845,6 @@ 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('')
|
||||
self.a_c_checkbox.setChecked(False)
|
||||
|
||||
|
|
@ -1005,15 +988,8 @@ def initialize(self, book_ids):
|
|||
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
|
||||
self.main_widget.blockSignals(True)
|
||||
for i, c in enumerate(self.all_values):
|
||||
if c == val:
|
||||
idx = i
|
||||
self.main_widget.addItem(c)
|
||||
self.main_widget.setEditText('')
|
||||
if idx is not None:
|
||||
self.main_widget.setCurrentIndex(idx)
|
||||
self.main_widget.show_initial_value(val)
|
||||
self.main_widget.blockSignals(False)
|
||||
|
||||
def commit(self, book_ids, notify=False):
|
||||
|
|
|
|||
|
|
@ -6,8 +6,7 @@
|
|||
|
||||
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.utils.icu import sort_key
|
||||
from calibre.ebooks.metadata import string_to_authors
|
||||
from calibre.gui2.complete import MultiCompleteComboBox
|
||||
from calibre.utils.config import tweaks
|
||||
|
||||
|
|
@ -56,17 +55,10 @@ def reset_author(self, *args):
|
|||
self.authors_combo.setEditText(_('Unknown'))
|
||||
|
||||
def initialize_authors(self, db, author):
|
||||
all_authors = db.all_authors()
|
||||
all_authors.sort(key=lambda x : sort_key(x[1]))
|
||||
for i in all_authors:
|
||||
id, name = i
|
||||
name = [name.strip().replace('|', ',') for n in name.split(',')]
|
||||
self.authors_combo.addItem(authors_to_string(name))
|
||||
|
||||
au = author
|
||||
if not au:
|
||||
au = _('Unknown')
|
||||
self.authors_combo.setEditText(au.replace('|', ','))
|
||||
self.authors_combo.show_initial_value(au.replace('|', ','))
|
||||
|
||||
self.authors_combo.set_separator('&')
|
||||
self.authors_combo.set_space_before_sep(True)
|
||||
|
|
|
|||
|
|
@ -876,38 +876,25 @@ def initalize_authors(self):
|
|||
all_authors = self.db.all_authors()
|
||||
all_authors.sort(key=lambda x : sort_key(x[1]))
|
||||
|
||||
for i in all_authors:
|
||||
id, name = i
|
||||
name = name.strip().replace('|', ',')
|
||||
self.authors.addItem(name)
|
||||
self.authors.setEditText('')
|
||||
|
||||
self.authors.set_separator('&')
|
||||
self.authors.set_space_before_sep(True)
|
||||
self.authors.set_add_separator(tweaks['authors_completer_append_separator'])
|
||||
self.authors.update_items_cache(self.db.all_author_names())
|
||||
self.authors.show_initial_value('')
|
||||
|
||||
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
|
||||
self.series.addItem(name)
|
||||
self.series.setEditText('')
|
||||
self.series.show_initial_value('')
|
||||
|
||||
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
|
||||
self.publisher.addItem(name)
|
||||
self.publisher.setEditText('')
|
||||
self.publisher.show_initial_value('')
|
||||
|
||||
def tag_editor(self, *args):
|
||||
d = TagEditor(self, self.db, None)
|
||||
|
|
|
|||
|
|
@ -25,10 +25,6 @@ def __init__(self, parent, db):
|
|||
|
||||
all_authors = db.all_authors()
|
||||
all_authors.sort(key=lambda x : sort_key(x[1]))
|
||||
for i in all_authors:
|
||||
id, name = i
|
||||
name = name.strip().replace('|', ',')
|
||||
self.authors_box.addItem(name)
|
||||
self.authors_box.setEditText('')
|
||||
self.authors_box.set_separator('&')
|
||||
self.authors_box.set_space_before_sep(True)
|
||||
|
|
@ -39,10 +35,7 @@ def __init__(self, parent, db):
|
|||
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.show_initial_value('')
|
||||
|
||||
all_tags = db.all_tags()
|
||||
self.tags_box.update_items_cache(all_tags)
|
||||
|
|
|
|||
|
|
@ -32,8 +32,6 @@ def init_langs(self, db):
|
|||
all_items = sorted(self._lang_map.itervalues(),
|
||||
key=lambda x: (-pmap.get(x, 0), sort_key(x)))
|
||||
self.update_items_cache(all_items)
|
||||
for item in all_items:
|
||||
self.addItem(item)
|
||||
|
||||
@property
|
||||
def vals(self):
|
||||
|
|
|
|||
|
|
@ -125,8 +125,6 @@ def createEditor(self, parent, option, index):
|
|||
editor.set_separator(None)
|
||||
complete_items = [i[1] for i in self.auto_complete_function()]
|
||||
editor.update_items_cache(complete_items)
|
||||
for item in sorted(complete_items, key=sort_key):
|
||||
editor.addItem(item)
|
||||
ct = index.data(Qt.DisplayRole).toString()
|
||||
editor.show_initial_value(ct)
|
||||
else:
|
||||
|
|
@ -166,8 +164,6 @@ def createEditor(self, parent, option, index):
|
|||
all_items = list(self.db.all_custom(
|
||||
label=self.db.field_metadata.key_to_label(col)))
|
||||
editor.update_items_cache(all_items)
|
||||
for item in sorted(all_items, key=sort_key):
|
||||
editor.addItem(item)
|
||||
ct = index.data(Qt.DisplayRole).toString()
|
||||
editor.show_initial_value(ct)
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -246,14 +246,6 @@ def get_default(self):
|
|||
|
||||
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]))
|
||||
self.clear()
|
||||
for i in all_authors:
|
||||
id, name = i
|
||||
name = name.strip().replace('|', ',')
|
||||
self.addItem(name)
|
||||
|
||||
self.set_separator('&')
|
||||
self.set_space_before_sep(True)
|
||||
self.set_add_separator(tweaks['authors_completer_append_separator'])
|
||||
|
|
@ -299,7 +291,6 @@ def fset(self, val):
|
|||
self.setEditText(' & '.join([x.strip() for x in val]))
|
||||
self.lineEdit().setCursorPosition(0)
|
||||
|
||||
|
||||
return property(fget=fget, fset=fset)
|
||||
|
||||
def break_cycles(self):
|
||||
|
|
@ -488,19 +479,12 @@ def initialize(self, db, id_):
|
|||
all_series.sort(key=lambda x : sort_key(x[1]))
|
||||
self.update_items_cache([x[1] for x in all_series])
|
||||
series_id = db.series_id(id_, index_is_id=True)
|
||||
idx, c = None, 0
|
||||
self.clear()
|
||||
inval = ''
|
||||
for i in all_series:
|
||||
id, name = i
|
||||
if id == series_id:
|
||||
idx = c
|
||||
self.addItem(name)
|
||||
c += 1
|
||||
|
||||
self.lineEdit().setText('')
|
||||
if idx is not None:
|
||||
self.setCurrentIndex(idx)
|
||||
self.original_val = self.current_val
|
||||
if i[0] == series_id:
|
||||
inval = i[1]
|
||||
break
|
||||
self.original_val = self.current_val = inval
|
||||
|
||||
def commit(self, db, id_):
|
||||
series = self.current_val
|
||||
|
|
@ -1373,17 +1357,12 @@ def initialize(self, db, id_):
|
|||
all_publishers.sort(key=lambda x : sort_key(x[1]))
|
||||
self.update_items_cache([x[1] for x in all_publishers])
|
||||
publisher_id = db.publisher_id(id_, index_is_id=True)
|
||||
idx = None
|
||||
self.clear()
|
||||
for i, x in enumerate(all_publishers):
|
||||
id_, name = x
|
||||
if id_ == publisher_id:
|
||||
idx = i
|
||||
self.addItem(name)
|
||||
|
||||
self.setEditText('')
|
||||
if idx is not None:
|
||||
self.setCurrentIndex(idx)
|
||||
inval = ''
|
||||
for pid, name in all_publishers:
|
||||
if pid == publisher_id:
|
||||
inval = name
|
||||
break
|
||||
self.original_val = self.current_val = inval
|
||||
|
||||
def commit(self, db, id_):
|
||||
self.books_to_refresh |= db.set_publisher(id_, self.current_val,
|
||||
|
|
|
|||
Loading…
Reference in a new issue