import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk, GObject from mods.files import choose_medicine_win_file, medicine_row_ui_str from mods.db import db, Rls, RlsIndex from mods.utils import enable_widget, disable_widget import re MAX_SEARCH_RESULTS = 50 def search_medicines(q): q = re.sub(r'\s+', ' ', q).strip() q = ' '.join([ f'{x}*' for x in q.split(' ')]) with db.atomic(): return (Rls.select() .join( RlsIndex, on=(Rls.id == RlsIndex.rowid)) .where(RlsIndex.match(q)) .order_by(RlsIndex.bm25()) .limit(MAX_SEARCH_RESULTS)) def get_all_medicines(): with db.atomic(): return Rls.select() def get_medicine(med_id): with db.atomic(): return Rls.get_by_id(med_id) ######################################################## class MedicineRow(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 @GObject.Property def tradename(self): return self._fio @tradename.setter def tradename_setter(self, value): self._fio = value def build_medicine_row(medicine): b = Gtk.Builder() b.add_from_string(medicine_row_ui_str) win = b.get_object('win') box = b.get_object('medicine_box') tradename = medicine.tradename b.get_object('tradename').set_text(tradename) internationalname = medicine.internationalname b.get_object('internationalname').set_text(internationalname) win.remove(win.get_children()[0]) row = MedicineRow() row.props.db_id = medicine.id row.props.tradename = tradename row.add(box) return row def create_choose_medicine_win(reception_b): b = Gtk.Builder() rm_list = reception_b.get_object('medicines_list') class ChooseMedicineWinHandler: def medicine_filter_changed(self, filter_widget): ml.unselect_all() self.medicine_list_unselected() for c in ml.get_children(): ml.remove(c) fstr = med_filter.get_text().strip() if fstr: for m in search_medicines(fstr): ml.add(build_medicine_row(m)) ml.show_all() def medicine_list_selected(self, *a): enable_widget([accept_button]) def medicine_list_unselected(self, *a): disable_widget([accept_button]) def submit(self, button): from mods.receptions import build_reception_medicine_row exist_rows = list(map(lambda x: x.props.db_id, rm_list.get_children())) row = ml.get_selected_row() if row.props.db_id not in exist_rows: medicine = get_medicine(row.props.db_id) rm_list.add(build_reception_medicine_row(medicine)) rm_list.show_all() w.destroy() b.add_from_file(choose_medicine_win_file) b.connect_signals(ChooseMedicineWinHandler()) accept_button = b.get_object('accept_button') ml = b.get_object('medicine_list') med_filter = b.get_object('medicine_filter') w = b.get_object('choose_medicine_window') return w