Fuzzy Search

This commit is contained in:
Jesper 2024-06-12 10:37:26 +02:00
parent d8820edd7d
commit cf76c4837e

View File

@ -8,6 +8,7 @@ import os
import subprocess
import threading
import urllib.request, urllib.parse, urllib.error
from fuzzywuzzy import process
import gi
gi.require_version("Gtk", "3.0")
@ -274,9 +275,11 @@ class pluginclass(object):
self.settings.connect("changed::fav-cols", self.changeFavCols)
self.settings.connect("changed::remember-filter", self.changeRememberFilter)
self.settings.connect("changed::enable-internet-search", self.changeEnableInternetSearch)
self.settings.connect("changed::enable-fuzzy-search", self.changeEnableFuzzySearch)
self.settings.connect("changed::category-hover-delay", self.GetGSettingsEntries)
self.settings.connect("changed::do-not-filter", self.GetGSettingsEntries)
self.settings.connect("changed::enable-internet-search", self.GetGSettingsEntries)
self.settings.connect("changed::enable-fuzzy-search", self.GetGSettingsEntries)
self.settings.connect("changed::search-command", self.GetGSettingsEntries)
self.settings.connect("changed::default-tab", self.GetGSettingsEntries)
self.settings.connect("changed::favorite-apps-list", self.favoriteAppsChanged)
@ -302,6 +305,7 @@ class pluginclass(object):
self.categoryList = []
self.applicationList = []
self.sortedApplicationList = []
#dirty ugly hack, to get favorites drag origin position
self.drag_origin = None
@ -441,6 +445,9 @@ class pluginclass(object):
def changeEnableInternetSearch(self, settings, key):
self.enableInternetSearch = settings.get_boolean(key)
def changeEnableFuzzySearch(self, settings, key):
self.enableFuzzySearch = settings.get_boolean(key)
def changeShowApplicationComments(self, settings, key):
self.showapplicationcomments = settings.get_boolean(key)
for child in self.applicationsBox:
@ -516,6 +523,7 @@ class pluginclass(object):
self.useAPT = self.settings.get_boolean("use-apt")
self.rememberFilter = self.settings.get_boolean("remember-filter")
self.enableInternetSearch = self.settings.get_boolean("enable-internet-search")
self.enableFuzzySearch = self.settings.get_boolean("enable-fuzzy-search")
self.lastActiveTab = self.settings.get_int("last-active-tab")
self.defaultTab = self.settings.get_int("default-tab")
@ -745,6 +753,30 @@ class pluginclass(object):
except Exception as e:
print(e)
def fuzzy_application_search(self, search_text):
for item in self.applicationList:
self.applicationsBox.remove(item["button"])
if search_text == "": # Reset application list
for item in self.applicationList:
self.applicationsBox.remove(item["button"])
for item in self.sortedApplicationList:
self.applicationsBox.pack_start(item[1], False, False, 0)
else: # Perform fuzzy search
labels = [app["button"].appName for app in self.applicationList]
results = process.extract(search_text, labels, limit=len(labels))
first_button = True
for match in results:
if match[1] > 60: # Adjust the threshold as needed
for app in self.applicationList:
if app["button"].appName == match[0]:
self.applicationsBox.pack_start(app["button"], False, False, 0)
if first_button is True:
app["button"].grab_focus()
first_button = False
def Filter(self, widget, category = None):
self.filterTimer = None
@ -760,29 +792,32 @@ class pluginclass(object):
if self.lastActiveTab != 1:
self.changeTab(1, clear = False)
text = widget.get_text()
showns = False # Are any app shown?
shownList = []
for i in self.applicationsBox.get_children():
shown = i.filterText(text)
if shown:
dupe = False
for item in shownList:
if i.desktopFile == item.desktopFile:
dupe = True
if dupe:
i.hide()
else:
shownList.append(i)
#if this is the first matching item
#focus it
if(not showns):
i.grab_focus()
showns = True
if not showns:
if len(text) >= 3:
self.add_search_suggestions(text)
if self.useAPT:
GLib.timeout_add(300, self.add_apt_filter_results, text)
# showns = False # Are any app shown?
# shownList = []
# for i in self.applicationsBox.get_children():
# shown = i.filterText(text)
# if shown:
# dupe = False
# for item in shownList:
# if i.desktopFile == item.desktopFile:
# dupe = True
# if dupe:
# i.hide()
# else:
# shownList.append(i)
# #if this is the first matching item
# #focus it
# if(not showns):
# i.grab_focus()
# showns = True
self.fuzzy_application_search(text)
# TODO Toggle self.enableFuzzySearch
# if not showns:
# if len(text) >= 3:
# self.add_search_suggestions(text)
# if self.useAPT:
# GLib.timeout_add(300, self.add_apt_filter_results, text)
for i in self.categoriesBox.get_children():
i.released()
i.set_relief(Gtk.ReliefStyle.NONE)
@ -809,7 +844,6 @@ class pluginclass(object):
i.released()
i.set_relief(Gtk.ReliefStyle.NONE)
widget.set_relief(Gtk.ReliefStyle.HALF)
self.applicationsScrolledWindow.get_vadjustment().set_value(0)
def FilterAndClear(self, widget, category = None):
@ -1592,10 +1626,10 @@ class pluginclass(object):
self.applicationList[key]["button"].destroy()
del self.applicationList[key]
if addedApplications:
sortedApplicationList = []
self.sortedApplicationList = []
for item in self.applicationList:
self.applicationsBox.remove(item["button"])
sortedApplicationList.append((item["button"].appName, item["button"]))
self.sortedApplicationList.append((item["button"].appName, item["button"]))
for item in addedApplications:
item["button"] = MenuApplicationLauncher(item["entry"].get_desktop_file_path(),
self.iconSize, item["category"], self.showapplicationcomments,
@ -1603,21 +1637,21 @@ class pluginclass(object):
if item["button"].appExec:
self.mintMenuWin.setTooltip(item["button"], item["button"].getTooltip())
item["button"].connect("button-press-event", self.menuPopup)
item["button"].connect("focus-in-event", self.scrollItemIntoView)
# item["button"].connect("focus-in-event", self.scrollItemIntoView)
item["button"].connect("clicked", RecentHelper.applicationButtonClicked)
if self.activeFilter[0] == 0:
item["button"].filterText(self.activeFilter[1])
else:
item["button"].filterCategory(self.activeFilter[1])
item["button"].desktop_file_path = item["entry"].get_desktop_file_path()
sortedApplicationList.append((item["button"].appName.upper(), item["button"]))
self.sortedApplicationList.append((item["button"].appName.upper(), item["button"]))
self.applicationList.append(item)
else:
item["button"].destroy()
sortedApplicationList.sort()
self.sortedApplicationList.sort()
launcherNames = [] # Keep track of launcher names so we don't add them twice in the list..
for item in sortedApplicationList:
for item in self.sortedApplicationList:
launcherName = item[0]
button = item[1]
self.applicationsBox.add(button)