mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 16:56:36 -04:00
search for multiple strings or tags in editor, more speedups
This commit is contained in:
parent
65d6194760
commit
24789281a5
2 changed files with 63 additions and 30 deletions
|
@ -44,7 +44,6 @@ class DeckModel(QAbstractTableModel):
|
||||||
(" "*10 + "Due" + " "*10, self.nextDue,
|
(" "*10 + "Due" + " "*10, self.nextDue,
|
||||||
"nextTime")]
|
"nextTime")]
|
||||||
self.searchStr = ""
|
self.searchStr = ""
|
||||||
self.tag = None
|
|
||||||
self.cards = []
|
self.cards = []
|
||||||
self.deleted = {}
|
self.deleted = {}
|
||||||
|
|
||||||
|
@ -96,30 +95,71 @@ class DeckModel(QAbstractTableModel):
|
||||||
# Filtering
|
# Filtering
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
|
def parseSearch(self):
|
||||||
|
search = self.searchStr
|
||||||
|
d = {'str': [],
|
||||||
|
'tag': [],
|
||||||
|
}
|
||||||
|
for elem in search.split():
|
||||||
|
if len(elem) > 2 and elem.startswith("t:"):
|
||||||
|
d['tag'].append(elem[2:])
|
||||||
|
else:
|
||||||
|
d['str'].append(elem)
|
||||||
|
return d
|
||||||
|
|
||||||
def showMatching(self):
|
def showMatching(self):
|
||||||
if not self.sortKey:
|
if not self.sortKey:
|
||||||
self.cards = []
|
self.cards = []
|
||||||
return
|
return
|
||||||
# searching
|
search = self.parseSearch()
|
||||||
searchLimit = ""
|
# text search
|
||||||
if self.searchStr:
|
textLimit = ""
|
||||||
searchLimit = "cards.factId in (%s)" % (
|
if search['str']:
|
||||||
",".join([str(x) for x in self.deck.s.column0(
|
ids = None
|
||||||
"select factId from fields where value like :val",
|
for s in search['str']:
|
||||||
val="%" + self.searchStr + "%")]))
|
i = self.deck.s.column0(
|
||||||
|
"select factId from fields where value like :s", s="%"+s+"%")
|
||||||
|
if not ids:
|
||||||
|
ids = set(i)
|
||||||
|
else:
|
||||||
|
ids.intersection_update(i)
|
||||||
|
if not ids:
|
||||||
|
break
|
||||||
|
if not ids:
|
||||||
|
ids = []
|
||||||
|
textLimit = "cards.factId in %s" % ids2str(ids)
|
||||||
# tags
|
# tags
|
||||||
tagLimit = ""
|
tagLimit = ""
|
||||||
if self.tag:
|
if search['tag']:
|
||||||
if self.tag == "notag":
|
ids = None
|
||||||
tagLimit = "cards.id in %s" % ids2str(self.deck.cardsWithNoTags())
|
if "none" in search['tag']:
|
||||||
|
search['tag'].remove("none")
|
||||||
|
ids = set(self.deck.cardsWithNoTags())
|
||||||
|
if search['tag']:
|
||||||
|
def find(tag, tags):
|
||||||
|
if tag.startswith('"'):
|
||||||
|
# direct match
|
||||||
|
return findTag(tag.replace('"', ""), parseTags(tags))
|
||||||
else:
|
else:
|
||||||
tagLimit = "cards.id in %s" % ids2str(
|
return tag.lower() in tags.lower()
|
||||||
[id for (id, tags, pri) in self.deck.tagsList()
|
for tag in search['tag']:
|
||||||
if findTag(self.tag, parseTags(tags))])
|
like = "%" + tag.replace('"', "") + "%"
|
||||||
|
i = [id for (id, tags, pri) in self.deck.tagsList(
|
||||||
|
where="""
|
||||||
|
and (facts.tags like :s or models.tags like :s)""",
|
||||||
|
kwargs = {'s': like})
|
||||||
|
if find(tag, tags)]
|
||||||
|
if not ids:
|
||||||
|
ids = set(i)
|
||||||
|
else:
|
||||||
|
ids.intersection_update(i)
|
||||||
|
if not ids:
|
||||||
|
ids = []
|
||||||
|
tagLimit = "cards.id in %s" % ids2str(ids)
|
||||||
# sorting
|
# sorting
|
||||||
sort = ""
|
sort = ""
|
||||||
ads = []
|
ads = []
|
||||||
if searchLimit: ads.append(searchLimit)
|
if textLimit: ads.append(textLimit)
|
||||||
if tagLimit: ads.append(tagLimit)
|
if tagLimit: ads.append(tagLimit)
|
||||||
ads = " and ".join(ads)
|
ads = " and ".join(ads)
|
||||||
if isinstance(self.sortKey, types.StringType):
|
if isinstance(self.sortKey, types.StringType):
|
||||||
|
@ -252,7 +292,6 @@ class EditDeck(QMainWindow):
|
||||||
|
|
||||||
def setupFilter(self):
|
def setupFilter(self):
|
||||||
self.filterTimer = None
|
self.filterTimer = None
|
||||||
self.currentTag = None
|
|
||||||
self.connect(self.dialog.filterEdit,
|
self.connect(self.dialog.filterEdit,
|
||||||
SIGNAL("textChanged(QString)"),
|
SIGNAL("textChanged(QString)"),
|
||||||
self.filterTextChanged)
|
self.filterTextChanged)
|
||||||
|
@ -279,12 +318,6 @@ class EditDeck(QMainWindow):
|
||||||
self.dialog.tagList.clear()
|
self.dialog.tagList.clear()
|
||||||
self.dialog.tagList.addItems(QStringList(
|
self.dialog.tagList.addItems(QStringList(
|
||||||
[_('All tags'), _('No tags')] + self.alltags))
|
[_('All tags'), _('No tags')] + self.alltags))
|
||||||
if self.currentTag:
|
|
||||||
try:
|
|
||||||
idx = self.alltags.index(self.currentTag) + 2
|
|
||||||
except ValueError:
|
|
||||||
idx = 0
|
|
||||||
self.dialog.tagList.setCurrentIndex(idx)
|
|
||||||
|
|
||||||
def drawSort(self):
|
def drawSort(self):
|
||||||
self.sortList = [
|
self.sortList = [
|
||||||
|
@ -359,12 +392,13 @@ class EditDeck(QMainWindow):
|
||||||
|
|
||||||
def tagChanged(self, idx):
|
def tagChanged(self, idx):
|
||||||
if idx == 0:
|
if idx == 0:
|
||||||
self.currentTag = None
|
self.dialog.filterEdit.setText("")
|
||||||
elif idx == 1:
|
elif idx == 1:
|
||||||
self.currentTag = "notag"
|
self.dialog.filterEdit.setText("t:none")
|
||||||
else:
|
else:
|
||||||
self.currentTag = self.alltags[idx-2]
|
self.dialog.filterEdit.setText(
|
||||||
self.updateSearch()
|
"t:\"" + self.alltags[idx-2] + "\"")
|
||||||
|
self.showFilterNow()
|
||||||
|
|
||||||
def updateFilterLabel(self):
|
def updateFilterLabel(self):
|
||||||
self.setWindowTitle(_("Editor (%(cur)d "
|
self.setWindowTitle(_("Editor (%(cur)d "
|
||||||
|
@ -410,7 +444,6 @@ class EditDeck(QMainWindow):
|
||||||
def updateSearch(self):
|
def updateSearch(self):
|
||||||
idx = self.dialog.tableView.currentIndex()
|
idx = self.dialog.tableView.currentIndex()
|
||||||
self.model.searchStr = unicode(self.dialog.filterEdit.text())
|
self.model.searchStr = unicode(self.dialog.filterEdit.text())
|
||||||
self.model.tag = self.currentTag
|
|
||||||
self.model.showMatching()
|
self.model.showMatching()
|
||||||
self.updateFilterLabel()
|
self.updateFilterLabel()
|
||||||
self.onEvent()
|
self.onEvent()
|
||||||
|
|
|
@ -333,7 +333,7 @@ order by n""", id=card.id)
|
||||||
newname = unicode(self.dialog.cardName.text())
|
newname = unicode(self.dialog.cardName.text())
|
||||||
if not newname:
|
if not newname:
|
||||||
newname = _("Card %d") % (self.m.cardModels.index(card) + 1)
|
newname = _("Card %d") % (self.m.cardModels.index(card) + 1)
|
||||||
self.updateField(card, 'name', newname)
|
self.updateField(card, 'name', newname.replace(" ", "-"))
|
||||||
s = unicode(self.dialog.cardQuestion.toPlainText())
|
s = unicode(self.dialog.cardQuestion.toPlainText())
|
||||||
s = s.replace("\n", "<br>")
|
s = s.replace("\n", "<br>")
|
||||||
changed = self.updateField(card, 'qformat', s)
|
changed = self.updateField(card, 'qformat', s)
|
||||||
|
@ -469,7 +469,7 @@ order by n""", id=card.id)
|
||||||
mname = _("Model")
|
mname = _("Model")
|
||||||
self.updateField(self.m, 'name', mname)
|
self.updateField(self.m, 'name', mname)
|
||||||
self.updateField(self.m, 'tags',
|
self.updateField(self.m, 'tags',
|
||||||
unicode(self.dialog.tags.text()))
|
unicode(self.dialog.tags.text()).replace(" ", "-"))
|
||||||
try:
|
try:
|
||||||
self.updateField(self.m, 'spacing',
|
self.updateField(self.m, 'spacing',
|
||||||
float(self.dialog.spacing.text()))
|
float(self.dialog.spacing.text()))
|
||||||
|
|
Loading…
Reference in a new issue