~fabrixxm/Collector

faf6cca1fcd1e95904dcf203e15b6b6bea57c2ab — fabrixxm 2 years ago 28987f9
Add completion to search entry

complete fields names and allowed values
2 files changed, 56 insertions(+), 3 deletions(-)

M src/pages.py
M src/widgets.py
M src/pages.py => src/pages.py +9 -3
@@ 27,9 27,10 @@ from gi.repository import Dazzle
from gi.repository import Handy

import lesana
import xapian

from .appsettings import AppSettings
from .widgets import PlaceholderWidget
from .widgets import PlaceholderWidget, CollectionSearchEntry
from .form import EntryForm

logger = logging.getLogger(__name__)


@@ 452,7 453,7 @@ class CollectionPageHeaderBar(BasePageTitleBar):

        column = Handy.Clamp(maximum_size=500, hexpand=True)
        box = Gtk.HBox()
        self.searchentry = Gtk.SearchEntry()
        self.searchentry = CollectionSearchEntry()
        self.searchentry.connect("search-changed", page.do_search)
        box.pack_start(self.searchentry, True, True, 4)
        box.pack_start(self.searchmenubtn, False, False, 0)


@@ 503,6 504,7 @@ class CollectionPageHeaderBar(BasePageTitleBar):
        for k in search_aliases.keys():
            self.searchmenumodel.append(k, f"win.searchalias({k!r})")
        self.searchmenubtn.set_visible(bool(search_aliases))
        self.searchentry.set_autocompletition(self.page.collection)

    def on_back_button_clicked(self, *args):
        win = self.page.window


@@ 557,7 559,11 @@ class CollectionPage(BaseListPage):
            self.collection.start_search("*")
            return self.collection.get_all_search_results()
        else:
            self.collection.start_search(self.query)
            try:
                self.collection.start_search(self.query)
            except xapian.QueryParserError as e:
                logger.info(e)

            return self.collection.get_all_search_results()

    def build_row(self, obj):

M src/widgets.py => src/widgets.py +47 -0
@@ 16,6 16,7 @@
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import logging
from gi.repository import GObject
from gi.repository import Gtk
from gi.repository import GtkSource



@@ 220,3 221,49 @@ class CommitDialog(Gtk.Dialog):

    def get_message(self):
        return self.message.get_text()


class CollectionSearchEntry(Gtk.SearchEntry):
    def __init__(self):
        super().__init__()
        self.model = Gtk.ListStore(GObject.TYPE_STRING)
        self.model.append(["culo"])
        completion = Gtk.EntryCompletion.new()
        completion.set_model(self.model)
        completion.set_text_column(0)
        completion.set_match_func(self._match)
        completion.connect("match-selected", self._match_selected)
        self.set_completion(completion)

    def _match(self, completion, key, iter, user_data=None) -> bool:

        cp = self.props.cursor_position
        k = key[:cp].split(" ")[-1]
        return self.model.get(iter, 0)[0].startswith(k)

    def _match_selected(self, completion, model, iter) -> bool:
        # replace the word under cursor position
        v = model.get(iter, 0)[0]

        t = self.get_text()
        cp = self.props.cursor_position
        pre = t[:cp].split(" ")[:-1]
        post = t[cp:].split(" ")[1:]
        newt = pre + [v] + post

        newcp = len(" ".join(pre)) + len(v) + 1

        self.set_text(" ".join(newt))
        self.emit("move_cursor", Gtk.MovementStep.LOGICAL_POSITIONS, -cp, False)
        self.emit("move_cursor", Gtk.MovementStep.LOGICAL_POSITIONS, newcp, False)
        return True

    def set_autocompletition(self, collection) -> None:
        self.model.clear()
        for field in collection.settings.get('fields', []):
            name = field.get('name', None)
            if name:
                self.model.append([f"{name}:"])
                if 'values' in field:
                    for value in field.get('values'):
                        self.model.append([f"{name}:{value} "])