eldoc/mods/lists.py

231 lines
9.1 KiB
Python
Raw Normal View History

import gi
gi.require_version('Gtk', '3.0')
2019-12-01 16:22:43 +03:00
from gi.repository import Gtk, GObject, Gdk
from mods.db import db, List, ListRecord, ListRecordIndex
2019-12-01 16:22:43 +03:00
from mods.files import open_list_win_file, listrecord_row_ui_str, editable_row_ui_str
from mods.utils import show_msg, disable_widget, enable_widget, ConditionalFilter
import re
import peewee
lists_map = {
'diagnoz': 'Диагноз',
'anamnez': 'Анамнез',
'observ': 'Осмотр',
'druggs': 'Медикаменты'
}
for s_id in lists_map:
with db.atomic():
q = List.select().where(List.system_id == s_id)
if not len(q):
List.create(name=lists_map[s_id], system_id=s_id)
2019-12-01 16:22:43 +03:00
class ListRecFilter(ConditionalFilter):
def filter(self, list_id, query):
if query != self.fstr:
self.fstr = query
self.ids = list(map(lambda x: x.id, self.search_func(list_id, query)))
return self.ids
class ListRecordRow(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 text(self):
return self._text
@text.setter
def text_setter(self, value):
self._text = value
def get_list(list_id):
with db.atomic():
return List.get_by_id(list_id)
2019-12-01 16:22:43 +03:00
def get_listrecord(listrec_id):
with db.atomic():
return ListRecord.get_by_id(listrec_id)
def get_all_list_records(list_id):
with db.atomic():
list_o = List.get_by_id(list_id)
return ListRecord.select().where(ListRecord.list == list_o)
def add_list_record(list_id, text):
with db.atomic():
list_o = List.get_by_id(list_id)
rec = ListRecord.create(list=list_o, text=text)
ListRecordIndex.insert(
{
ListRecordIndex.rowid: rec.id,
ListRecordIndex.text: text
}
).execute()
return rec
def delete_list_record(listrec_id):
with db.atomic():
ListRecord.delete().where(ListRecord.id == listrec_id).execute()
ListRecordIndex.delete().where(ListRecordIndex.rowid == listrec_id).execute()
def change_list_record(listrec_id, new_text):
2019-12-01 16:22:43 +03:00
listrec_o = get_listrecord(listrec_id)
if listrec_o.text == new_text:
2019-12-01 16:22:43 +03:00
return listrec_o
with db.atomic():
2019-12-01 16:22:43 +03:00
ListRecord.update(text=new_text).where(ListRecord.id == listrec_id).execute()
ListRecordIndex.update(text=new_text).where(ListRecordIndex.rowid == listrec_id).execute()
return ListRecord.get_by_id(listrec_id)
def search_list_record(list_id, q):
2019-12-01 16:22:43 +03:00
q = re.sub(r'\s+', ' ', q).strip()
q = ' '.join([ f'{x}*' for x in q.split(' ')])
list_o = get_list(list_id)
with db.atomic():
return (ListRecord.select()
.join(
ListRecordIndex,
on=(ListRecord.id == ListRecordIndex.rowid))
.where((ListRecord.list == list_o) & (ListRecordIndex.match(q)))
.order_by(ListRecordIndex.bm25()))
2019-12-01 16:22:43 +03:00
#####################################################################################################################
def build_listrecord_row(listrec_o):
b = Gtk.Builder()
b.add_from_string(listrecord_row_ui_str)
win = b.get_object('win')
box = b.get_object('listrecord_box')
b.get_object('text').set_text(listrec_o.text)
row = ListRecordRow()
row.props.db_id = listrec_o.id
row.text = listrec_o.text
win.remove(win.get_children()[0])
row.add(box)
return row
def build_listrec_editable_row(listrec_o=None):
b = Gtk.Builder()
b.add_from_string(editable_row_ui_str)
#b.connect_signals({'editing_done': listrec_editing_done})
win = b.get_object('win')
box = b.get_object('editable_box')
text_input = b.get_object('text_input')
text_input.set_text(listrec_o.text if listrec_o else '')
row = ListRecordRow()
row.props.db_id = listrec_o.id if listrec_o else -1
row.text = listrec_o.text if listrec_o else ''
win.remove(win.get_children()[0])
row.add(box)
return (row, text_input)
def create_open_list_win(list_id):
list_o = get_list(list_id)
b = Gtk.Builder()
2019-12-01 16:22:43 +03:00
listrecord_filter = ListRecFilter(search_list_record)
class OpenListHandler:
2019-12-01 16:22:43 +03:00
def row_add_cancel(self, entry, ev, row):
if ev.keyval == Gdk.KEY_Escape:
lr_list.remove(row)
row.destroy()
def row_edit_cancel(self, entry, ev, edit_row):
if ev.keyval == Gdk.KEY_Escape:
rec = get_listrecord(edit_row.props.db_id)
row = build_listrecord_row(rec)
lr_list.remove(edit_row)
edit_row.destroy()
lr_list.add(row)
lr_list.show_all()
def enable_buttons_on_add_edit(self, *a):
enable_widget([add_button, edit_button, remove_button, lr_filter])
def remove_row(self, button):
row = lr_list.get_selected_row()
delete_list_record(row.props.db_id)
lr_list.remove(row)
row.destroy()
lr_list.show_all()
self.listrec_row_unselected()
def edit_row(self, button):
row = lr_list.get_selected_row()
rec = get_listrecord(row.props.db_id)
(edit_row, inp) = build_listrec_editable_row(rec)
lr_list.remove(row)
row.destroy()
lr_list.add(edit_row)
inp.grab_focus()
inp.connect('key-release-event', self.row_edit_cancel, edit_row)
inp.connect('activate', self.update_row, edit_row)
inp.connect('destroy', self.enable_buttons_on_add_edit)
disable_widget([add_button, edit_button, remove_button, lr_filter])
lr_list.show_all()
def add_new_row(self, button):
(row, text_input) = build_listrec_editable_row()
lr_list.add(row)
text_input.grab_focus()
text_input.connect('key-release-event', self.row_add_cancel, row)
text_input.connect('activate', self.save_new_row, row)
text_input.connect('destroy', self.enable_buttons_on_add_edit)
disable_widget([add_button, edit_button, remove_button, lr_filter])
lr_list.show_all()
def update_row(self, inp, edit_row):
new_text = re.sub(r'\s+', ' ', inp.get_text()).strip()
if new_text:
try:
rec = change_list_record(edit_row.props.db_id, new_text)
except peewee.IntegrityError:
return show_msg('Такая же запись уже существует', 'В данном списке уже существует\nдругая запись с данным текстом', level='warn')
row = build_listrecord_row(rec)
else:
row = build_listrecord_row(get_listrecord(edit_row.props.db_id))
lr_list.add(row)
lr_list.select_row(row)
lr_list.show_all()
lr_list.remove(edit_row)
edit_row.destroy()
def save_new_row(self, inp, row):
row_text = re.sub(r'\s+', ' ', inp.get_text()).strip()
if row_text:
try:
rec = add_list_record(list_id, row_text)
except peewee.IntegrityError:
return show_msg('Данная запись уже существует', 'В данном списке уже существует\nзапись с данным текстом', level='warn')
new_row = build_listrecord_row(rec)
lr_list.add(new_row)
lr_list.select_row(new_row)
lr_list.show_all()
lr_list.remove(row)
row.destroy()
def listrec_row_selected(self, *a):
enable_widget([edit_button, remove_button])
def listrec_row_unselected(self, *a):
disable_widget([edit_button, remove_button])
def listrec_filter_changed(self, filter_widget):
lr_list.unselect_all()
self.listrec_row_unselected()
lr_list.invalidate_filter()
b.add_from_file(open_list_win_file)
b.connect_signals(OpenListHandler())
2019-12-01 16:22:43 +03:00
# Gtk objects
w = b.get_object('open_list_window')
2019-12-01 16:22:43 +03:00
lr_list = b.get_object('listrecord_list')
lr_filter = b.get_object('listrecord_filter')
add_button = b.get_object('add_button')
edit_button = b.get_object('edit_button')
remove_button = b.get_object('remove_button')
list_header = b.get_object('list_win_header')
2019-12-01 16:22:43 +03:00
#############
######
def listrecord_sort_func(row1, row2, *a):
text1 = row1.props.text
text2 = row2.props.text
return (text1 > text2) - (text1 < text2)
def listrecord_filter_func(row):
fstr = lr_filter.get_text().strip()
if not fstr:
listrecord_filter.reset()
return True
return row.props.db_id in listrecord_filter.filter(list_id, fstr)
######
lr_list.set_sort_func(listrecord_sort_func)
lr_list.set_filter_func(listrecord_filter_func)
list_header.props.title = list_o.name
for lr in get_all_list_records(list_id):
2019-12-01 16:22:43 +03:00
lr_list.add(build_listrecord_row(lr))
return w