Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 57 additions & 8 deletions tabtabtab.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,27 @@ def find_menu_items(menu, _path = None):
return found


def consec_find(needle, haystack, anchored = False):
''' searches for the "needle" string in the "haystack" string.
added to tabtabtab as a way to prioritize more relevant results.
'''

if "[" not in needle:
haystack = haystack.rpartition(" [")[0]

stripped_haystack = haystack.replace(' ','').replace('-','').replace('_','')

if anchored:
if haystack.startswith(needle) or stripped_haystack.startswith(needle):
return True

else:
if needle in haystack or needle in stripped_haystack:
return True
return False



def nonconsec_find(needle, haystack, anchored = False):
"""checks if each character of "needle" can be found in order (but not
necessarily consecutivly) in haystack.
Expand Down Expand Up @@ -227,7 +248,7 @@ def increment(self, key):


class NodeModel(QtCore.QAbstractListModel):
def __init__(self, mlist, weights, num_items = 15, filtertext = ""):
def __init__(self, mlist, weights, num_items = 18, filtertext = ""):
super(NodeModel, self).__init__()

self.weights = weights
Expand All @@ -243,31 +264,59 @@ def __init__(self, mlist, weights, num_items = 15, filtertext = ""):
def set_filter(self, filtertext):
self._filtertext = filtertext
self.update()

def update(self):
filtertext = self._filtertext.lower()

# Two spaces as a shortcut for [
filtertext = filtertext.replace(" ", "[")

scored = []

anchored = True
force_non_anchored = False
# Starting the string with * or [ disables anchoring.
# Starting with ** forces non anchored results
if filtertext.startswith('*') or filtertext.startswith('['):
anchored = False
filtertext = filtertext.replace("*", "", 1)
if filtertext.startswith('*'):
force_non_anchored = True
filtertext = filtertext.replace("*", "")

scored_a = []
scored_b = []
for n in self._all:
# Turn "3D/Shader/Phong" into "Phong [3D/Shader]"
menupath = n['menupath'].replace("&", "")
uiname = "%s [%s]" % (menupath.rpartition("/")[2], menupath.rpartition("/")[0])
search_string = uiname.lower()

if force_non_anchored:
search_string = search_string[1:]

if consec_find(filtertext, search_string, anchored):
# Matches, get weighting and add to list of stuff
score = self.weights.get(n['menupath'])

scored_a.append({
'text': uiname,
'menupath': n['menupath'],
'menuobj': n['menuobj'],
'score': score})

if nonconsec_find(filtertext, uiname.lower(), anchored=True):
elif nonconsec_find(filtertext, search_string, anchored):
# Matches, get weighting and add to list of stuff
score = self.weights.get(n['menupath'])

scored.append({
scored_b.append({
'text': uiname,
'menupath': n['menupath'],
'menuobj': n['menuobj'],
'score': score})

# Store based on scores (descending), then alphabetically
s = sorted(scored, key = lambda k: (-k['score'], k['text']))
# Sort based on scores (descending), then alphabetically
sort_a = sorted(scored_a, key = lambda k: (-k['score'], k['text']))
sort_b = sorted(scored_b, key = lambda k: (-k['score'], k['text']))
s = sort_a + sort_b

self._items = s
self.modelReset.emit()
Expand Down