search for multiple strings or tags in editor, more speedups

This commit is contained in:
Damien Elmes 2009-02-08 03:21:00 +09:00
parent 65d6194760
commit 24789281a5
2 changed files with 63 additions and 30 deletions

View file

@ -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()

View file

@ -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()))