2019-11-23 23:36:26 +03:00
|
|
|
|
import gi
|
|
|
|
|
gi.require_version('Gtk', '3.0')
|
2019-12-01 16:22:43 +03:00
|
|
|
|
from gi.repository import Gtk, GObject, Gdk
|
2019-11-23 23:36:26 +03:00
|
|
|
|
from mods.db import db, List, ListRecord, ListRecordIndex
|
2019-12-12 19:47:08 +03:00
|
|
|
|
from mods.files import open_list_win_file, listrecord_row_ui_str, editable_row_ui_str, list_row_ui_str
|
2019-12-01 16:22:43 +03:00
|
|
|
|
from mods.utils import show_msg, disable_widget, enable_widget, ConditionalFilter
|
|
|
|
|
import re
|
|
|
|
|
import peewee
|
2019-11-23 23:36:26 +03:00
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
2019-12-12 19:47:08 +03:00
|
|
|
|
class ListRow(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 name(self):
|
|
|
|
|
return self._name
|
|
|
|
|
@name.setter
|
|
|
|
|
def name_setter(self, value):
|
|
|
|
|
self._name = value
|
|
|
|
|
|
2019-11-23 23:36:26 +03:00
|
|
|
|
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)
|
2019-11-23 23:36:26 +03:00
|
|
|
|
|
|
|
|
|
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)
|
2019-11-23 23:36:26 +03:00
|
|
|
|
if listrec_o.text == new_text:
|
2019-12-01 16:22:43 +03:00
|
|
|
|
return listrec_o
|
2019-11-23 23:36:26 +03:00
|
|
|
|
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)
|
2019-11-23 23:36:26 +03:00
|
|
|
|
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)
|
2019-11-23 23:36:26 +03:00
|
|
|
|
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
|
|
|
|
#####################################################################################################################
|
2019-12-12 19:47:08 +03:00
|
|
|
|
def build_list_row(list_o):
|
|
|
|
|
b = Gtk.Builder()
|
|
|
|
|
b.add_from_string(list_row_ui_str)
|
|
|
|
|
win = b.get_object('win')
|
|
|
|
|
box = b.get_object('list_box')
|
|
|
|
|
b.get_object('name').set_text(list_o.name)
|
|
|
|
|
row = ListRow()
|
|
|
|
|
row.props.db_id = list_o.id
|
|
|
|
|
row.name = list_o.name
|
|
|
|
|
win.remove(win.get_children()[0])
|
|
|
|
|
row.add(box)
|
|
|
|
|
return row
|
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)
|
2019-11-23 23:36:26 +03:00
|
|
|
|
|
|
|
|
|
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)
|
2019-11-23 23:36:26 +03:00
|
|
|
|
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()
|
2019-12-12 19:47:08 +03:00
|
|
|
|
lr_list.unselect_all()
|
|
|
|
|
self.listrec_row_unselected()
|
2019-12-01 16:22:43 +03:00
|
|
|
|
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()
|
2019-11-23 23:36:26 +03:00
|
|
|
|
b.add_from_file(open_list_win_file)
|
|
|
|
|
b.connect_signals(OpenListHandler())
|
2019-12-01 16:22:43 +03:00
|
|
|
|
# Gtk objects
|
2019-11-23 23:36:26 +03:00
|
|
|
|
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')
|
2019-11-23 23:36:26 +03:00
|
|
|
|
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)
|
2019-11-23 23:36:26 +03:00
|
|
|
|
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))
|
2019-11-23 23:36:26 +03:00
|
|
|
|
return w
|
|
|
|
|
|