import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk, GObject from mods.files import choose_diagnosis_win_file, diagnosis_row_ui_str from mods.utils import ConditionalFilter from mods.db import DiagnosisCategory, Diagnosis, DiagnosisIndex, db import re class DiagnosisFilter(ConditionalFilter): def filter(self, cat, query): if query != self.fstr: self.fstr = query self.ids = list(map(lambda x:x.id, self.search_func(cat, query))) return self.ids class DiagnosisRow(Gtk.ListBoxRow): @GObject.Property def db_id(self): return self._db_id @db_id.setter def db_id_setter(self, value): self._db_id = value def cats_subcats(cat): cats = [cat] def append_cat(cat_obj): cats.append(cat_obj) for c in cat_obj.subcat: append_cat(c) for c in cat.subcat: append_cat(c) return cats def get_categories(parent=None): with db.atomic(): return DiagnosisCategory.select().where(DiagnosisCategory.parent == parent) def get_diagnosises(cat=None): with db.atomic(): if cat: d = list(Diagnosis.select().where(Diagnosis.category.in_(cats_subcats(cat))).order_by(Diagnosis.code)) return d else: return Diagnosis.select() def get_category(cat_id): with db.atomic(): return DiagnosisCategory.get_by_id(cat_id) def search_diagnosises(cat, q): q = re.sub(r'\s+', ' ', q).strip() q = ' '.join([ f'{x}*' for x in q.split(' ')]) with db.atomic(): return (Diagnosis.select() .join( DiagnosisIndex, on=(Diagnosis.id == DiagnosisIndex.rowid)) .where((Diagnosis.category.in_(cats_subcats(cat))) & (DiagnosisIndex.match(q))) .order_by(DiagnosisIndex.bm25())) diagnosis_filter = DiagnosisFilter(search_diagnosises) ######################################################## def build_diagnosis_row(diagnosis): b = Gtk.Builder() b.add_from_string(diagnosis_row_ui_str) win = b.get_object('win') box = b.get_object('diagnosis_box') b.get_object('title').set_markup(f'{diagnosis.code:<8} {diagnosis.title}') win.remove(win.get_children()[0]) row = DiagnosisRow() row.props.db_id = diagnosis.id row.add(box) return row def create_choose_diagnosis_win(reception): b = Gtk.Builder() class ChooseDiagnosisWinHandler: def cat_selection_changed(self, cat_selection): sel_iter = cat_selection.get_selected()[1] model = cat_selection.get_tree_view().get_model() category = get_category(model.get_value(sel_iter, 1)) self.redraw_diagnosis_list(category) def redraw_diagnosis_list(self, cat): for c in diagnosis_list.get_children(): diagnosis_list.remove(c) for d in get_diagnosises(cat): diagnosis_list.add(build_diagnosis_row(d)) diagnosis_list.show_all() b.add_from_file(choose_diagnosis_win_file) b.connect_signals(ChooseDiagnosisWinHandler()) cat_liststore = b.get_object('category_list') def insert_cat(cat, parent=None): cur_parent = cat_liststore.append(parent, [cat.title, cat.id]) for c in get_categories(cat): insert_cat(c, cur_parent) for c in get_categories(): insert_cat(c) diagnosis_list = b.get_object('diagnosis_list') diagnosis_list.set_sort_func(None, None) w = b.get_object('choose_diagnosis_window') return w