mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Make tags completing line edit a stand alone widget. Use tag completing line edit in metadata single dialog.
This commit is contained in:
parent
60bc41b33e
commit
b8fc9de71d
@ -268,7 +268,8 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
|
||||
aus = self.db.author_sort(row)
|
||||
self.author_sort.setText(aus if aus else '')
|
||||
tags = self.db.tags(row)
|
||||
self.tags.setText(tags if tags else '')
|
||||
self.tags.setText(', '.join(tags.split(',')) if tags else '')
|
||||
self.tags.update_tags_cache(self.db.all_tags())
|
||||
rating = self.db.rating(row)
|
||||
if rating > 0:
|
||||
self.rating.setValue(int(rating/2.))
|
||||
@ -389,6 +390,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
|
||||
if d.result() == QDialog.Accepted:
|
||||
tag_string = ', '.join(d.tags)
|
||||
self.tags.setText(tag_string)
|
||||
self.tags.update_tags_cache(self.db.all_tags())
|
||||
|
||||
def fetch_cover(self):
|
||||
isbn = unicode(self.isbn.text()).strip()
|
||||
|
@ -222,7 +222,7 @@
|
||||
<item row="5" column="1" colspan="2">
|
||||
<layout class="QHBoxLayout" name="_2">
|
||||
<item>
|
||||
<widget class="EnLineEdit" name="tags">
|
||||
<widget class="TagsLineEdit" name="tags">
|
||||
<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>
|
||||
</property>
|
||||
@ -652,6 +652,11 @@
|
||||
<extends>QComboBox</extends>
|
||||
<header>widgets.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>TagsLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>widgets.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>title</tabstop>
|
||||
|
@ -19,7 +19,7 @@ from calibre.ptempfile import PersistentTemporaryFile
|
||||
from calibre.library.database2 import FIELD_MAP
|
||||
from calibre.gui2 import NONE, TableView, qstring_to_unicode, config, \
|
||||
error_dialog
|
||||
from calibre.gui2.widgets import EnLineEdit
|
||||
from calibre.gui2.widgets import EnLineEdit, TagsLineEdit
|
||||
from calibre.utils.search_query_parser import SearchQueryParser
|
||||
from calibre.ebooks.metadata.meta import set_metadata as _set_metadata
|
||||
from calibre.ebooks.metadata import string_to_authors, fmt_sidx
|
||||
@ -118,50 +118,6 @@ class TextDelegate(QStyledItemDelegate):
|
||||
editor = EnLineEdit(parent)
|
||||
return editor
|
||||
|
||||
class CompleterLineEdit(EnLineEdit):
|
||||
|
||||
def __init__(self, *args):
|
||||
EnLineEdit.__init__(self, *args)
|
||||
|
||||
QObject.connect(self, SIGNAL('textChanged(QString)'), self.text_changed)
|
||||
|
||||
def text_changed(self, text):
|
||||
all_text = qstring_to_unicode(text)
|
||||
text = all_text[:self.cursorPosition()]
|
||||
prefix = text.split(',')[-1].strip()
|
||||
|
||||
text_tags = []
|
||||
for t in all_text.split(','):
|
||||
t1 = qstring_to_unicode(t).strip()
|
||||
if t1 != '':
|
||||
text_tags.append(t)
|
||||
text_tags = list(set(text_tags))
|
||||
|
||||
self.emit(SIGNAL('text_changed(PyQt_PyObject, PyQt_PyObject)'), text_tags, prefix)
|
||||
|
||||
def complete_text(self, text):
|
||||
cursor_pos = self.cursorPosition()
|
||||
before_text = qstring_to_unicode(self.text())[:cursor_pos]
|
||||
after_text = qstring_to_unicode(self.text())[cursor_pos:]
|
||||
prefix_len = len(before_text.split(',')[-1].strip())
|
||||
self.setText('%s%s, %s' % (before_text[:cursor_pos - prefix_len], text, after_text))
|
||||
self.setCursorPosition(cursor_pos - prefix_len + len(text) + 2)
|
||||
|
||||
class TagsCompleter(QCompleter):
|
||||
|
||||
def __init__(self, parent, all_tags):
|
||||
QCompleter.__init__(self, all_tags, parent)
|
||||
self.all_tags = set(all_tags)
|
||||
|
||||
def update(self, text_tags, completion_prefix):
|
||||
tags = list(self.all_tags.difference(text_tags))
|
||||
model = QStringListModel(tags, self)
|
||||
self.setModel(model)
|
||||
|
||||
self.setCompletionPrefix(completion_prefix)
|
||||
if completion_prefix.strip() != '':
|
||||
self.complete()
|
||||
|
||||
class TagsDelegate(QStyledItemDelegate):
|
||||
|
||||
def __init__(self, parent):
|
||||
@ -172,18 +128,10 @@ class TagsDelegate(QStyledItemDelegate):
|
||||
self.db = db
|
||||
|
||||
def createEditor(self, parent, option, index):
|
||||
editor = CompleterLineEdit(parent)
|
||||
if self.db:
|
||||
completer = TagsCompleter(editor, self.db.all_tags())
|
||||
completer.setCaseSensitivity(Qt.CaseInsensitive)
|
||||
|
||||
QObject.connect(editor,
|
||||
SIGNAL('text_changed(PyQt_PyObject, PyQt_PyObject)'),
|
||||
completer.update)
|
||||
QObject.connect(completer, SIGNAL('activated(QString)'),
|
||||
editor.complete_text)
|
||||
|
||||
completer.setWidget(editor)
|
||||
editor = TagsLineEdit(parent, self.db.all_tags())
|
||||
else:
|
||||
editor = EnLineEdit(parent)
|
||||
return editor
|
||||
|
||||
class BooksModel(QAbstractTableModel):
|
||||
|
@ -11,7 +11,7 @@ from PyQt4.Qt import QListView, QIcon, QFont, QLabel, QListWidget, \
|
||||
QAbstractListModel, QVariant, Qt, SIGNAL, \
|
||||
QRegExp, QSettings, QSize, QModelIndex, \
|
||||
QAbstractButton, QPainter, QLineEdit, QComboBox, \
|
||||
QMenu
|
||||
QMenu, QStringListModel, QCompleter
|
||||
|
||||
from calibre.gui2 import human_readable, NONE, TableView, \
|
||||
qstring_to_unicode, error_dialog
|
||||
@ -500,6 +500,84 @@ class EnLineEdit(LineEditECM, QLineEdit):
|
||||
pass
|
||||
|
||||
|
||||
class TagsCompleter(QCompleter):
|
||||
|
||||
'''
|
||||
A completer object that completes a list of tags. It is used in conjunction
|
||||
with a CompleterLineEdit.
|
||||
'''
|
||||
|
||||
def __init__(self, parent, all_tags):
|
||||
QCompleter.__init__(self, all_tags, parent)
|
||||
self.all_tags = set(all_tags)
|
||||
|
||||
def update(self, text_tags, completion_prefix):
|
||||
tags = list(self.all_tags.difference(text_tags))
|
||||
model = QStringListModel(tags, self)
|
||||
self.setModel(model)
|
||||
|
||||
self.setCompletionPrefix(completion_prefix)
|
||||
if completion_prefix.strip() != '':
|
||||
self.complete()
|
||||
|
||||
def update_tags_cache(self, tags):
|
||||
self.all_tags = set(tags)
|
||||
model = QStringListModel(tags, self)
|
||||
self.setModel(model)
|
||||
|
||||
|
||||
class TagsLineEdit(EnLineEdit):
|
||||
|
||||
'''
|
||||
A QLineEdit that can complete parts of text separated by separator.
|
||||
'''
|
||||
|
||||
def __init__(self, parent=0, tags=[]):
|
||||
EnLineEdit.__init__(self, parent)
|
||||
|
||||
self.separator = ','
|
||||
|
||||
self.connect(self, SIGNAL('textChanged(QString)'), self.text_changed)
|
||||
|
||||
self.completer = TagsCompleter(self, tags)
|
||||
self.completer.setCaseSensitivity(Qt.CaseInsensitive)
|
||||
|
||||
self.connect(self,
|
||||
SIGNAL('text_changed(PyQt_PyObject, PyQt_PyObject)'),
|
||||
self.completer.update)
|
||||
self.connect(self.completer, SIGNAL('activated(QString)'),
|
||||
self.complete_text)
|
||||
|
||||
self.completer.setWidget(self)
|
||||
|
||||
def update_tags_cache(self, tags):
|
||||
self.completer.update_tags_cache(tags)
|
||||
|
||||
def text_changed(self, text):
|
||||
all_text = qstring_to_unicode(text)
|
||||
text = all_text[:self.cursorPosition()]
|
||||
prefix = text.split(',')[-1].strip()
|
||||
|
||||
text_tags = []
|
||||
for t in all_text.split(self.separator):
|
||||
t1 = qstring_to_unicode(t).strip()
|
||||
if t1 != '':
|
||||
text_tags.append(t)
|
||||
text_tags = list(set(text_tags))
|
||||
|
||||
self.emit(SIGNAL('text_changed(PyQt_PyObject, PyQt_PyObject)'),
|
||||
text_tags, prefix)
|
||||
|
||||
def complete_text(self, text):
|
||||
cursor_pos = self.cursorPosition()
|
||||
before_text = qstring_to_unicode(self.text())[:cursor_pos]
|
||||
after_text = qstring_to_unicode(self.text())[cursor_pos:]
|
||||
prefix_len = len(before_text.split(',')[-1].strip())
|
||||
self.setText('%s%s%s %s' % (before_text[:cursor_pos - prefix_len],
|
||||
text, self.separator, after_text))
|
||||
self.setCursorPosition(cursor_pos - prefix_len + len(text) + 2)
|
||||
|
||||
|
||||
class EnComboBox(QComboBox):
|
||||
|
||||
'''
|
||||
|
Loading…
x
Reference in New Issue
Block a user