149 lines
5.9 KiB
Python
149 lines
5.9 KiB
Python
import gi
|
||
import os
|
||
gi.require_version('Gtk', '3.0')
|
||
from gi.repository import Gtk, GObject
|
||
from mods.db import Patient, store_patient_index, search_patients, db
|
||
from datetime import date
|
||
import peewee
|
||
|
||
resource_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'res')
|
||
ui_dir = os.path.join(resource_dir, 'ui')
|
||
main_win_file = os.path.join(ui_dir, 'main_win.glade')
|
||
new_patient_win_file = os.path.join(ui_dir, 'new_patient_win.glade')
|
||
|
||
builder = Gtk.Builder()
|
||
|
||
class PatientFilter:
|
||
def __init__(self):
|
||
self.reset()
|
||
def filter(self, query):
|
||
if query != self.fstr:
|
||
self.fstr = query
|
||
self.ids = list(map(lambda x: x.id, search_patients(query)))
|
||
return self.ids
|
||
def reset(self):
|
||
self.fstr = ''
|
||
self.ids = []
|
||
patient_filter = PatientFilter()
|
||
|
||
class PatientRow(Gtk.ListBoxRow):
|
||
@GObject.Property
|
||
def db_id(self):
|
||
return self._db_id
|
||
|
||
@db_id.setter
|
||
def my_custom_property(self, value):
|
||
self._db_id = value
|
||
|
||
class MainWinHandler:
|
||
def main_win_close(self, *args):
|
||
Gtk.main_quit()
|
||
def show_new_patient_win(self, button):
|
||
new_patient_win = create_new_patient_win()
|
||
new_patient_win.show_all()
|
||
def patient_filter_changed(self, filter_widget):
|
||
pl = builder.get_object('patient_list')
|
||
pl.unselect_all()
|
||
pl.invalidate_filter()
|
||
'''pl = builder.get_object('patient_list')
|
||
for r in pl.get_children():
|
||
pl.remove(r)
|
||
fstr = builder.get_object('patient_filter').get_text().strip()
|
||
if not fstr:
|
||
for p in Patient.select():
|
||
pl.add(build_patient_row(p))
|
||
else:
|
||
patients = search_patients(fstr)
|
||
for p in patients:
|
||
pl.add(build_patient_row(p))
|
||
pl.show_all()'''
|
||
|
||
def build_patient_row(patient):
|
||
row = PatientRow()
|
||
row.props.db_id = patient.id
|
||
label = Gtk.Label(f'{" ".join([patient.last_name, patient.first_name, patient.middle_name])}, {patient.birth_date}', xalign=0)
|
||
row.add(label)
|
||
return row
|
||
def patient_sort_func(row1, row2, *a):
|
||
text1 = row1.get_children()[0].get_text()
|
||
text2 = row2.get_children()[0].get_text()
|
||
return (text1 > text2) - (text1 < text2)
|
||
def patient_filter_func(row):
|
||
fstr = builder.get_object('patient_filter').get_text().strip()
|
||
if not fstr:
|
||
patient_filter.reset()
|
||
return True
|
||
return row.props.db_id in patient_filter.filter(fstr)
|
||
|
||
builder.add_from_file(main_win_file)
|
||
builder.connect_signals(MainWinHandler())
|
||
patient_list = builder.get_object('patient_list')
|
||
patient_list.set_sort_func(patient_sort_func)
|
||
patient_list.set_filter_func(patient_filter_func)
|
||
with db.atomic():
|
||
for p in Patient.select():
|
||
patient_list.add(build_patient_row(p))
|
||
|
||
def show_msg(text, sec_text='', level='info'):
|
||
msg_win_file = os.path.join(ui_dir, f'{level}_win.glade')
|
||
b = Gtk.Builder()
|
||
b.add_from_file(msg_win_file)
|
||
w = b.get_object(level)
|
||
w.set_property('text',text)
|
||
w.set_property('secondary_text',sec_text)
|
||
w.run()
|
||
w.close()
|
||
|
||
def create_new_patient_win():
|
||
b = Gtk.Builder()
|
||
class NewPatienWinHandler:
|
||
def only_digits(self, entry):
|
||
text = entry.get_text()
|
||
text = ''.join(filter(lambda x: x.isdigit(), text))
|
||
entry.set_text(text)
|
||
def save_patient(self, *args):
|
||
l_name = b.get_object('last_name').get_text().replace(' ', '')
|
||
f_name = b.get_object('first_name').get_text().replace(' ', '')
|
||
m_name = b.get_object('middle_name').get_text().replace(' ', '')
|
||
if '' in (l_name, f_name):
|
||
return show_msg('Не указаны имя или фамилия', 'Данные поля должны быть заполнены', level='warn')
|
||
try:
|
||
birth_d = int(b.get_object('birth_day').get_text())
|
||
if birth_d < 1 or birth_d > 31:
|
||
return show_msg('Неверный день месяца', 'Укажите число в диапазоне 1-31', level='warn')
|
||
birth_m = int(b.get_object('birth_month').get_text())
|
||
if birth_m < 1 or birth_m > 12:
|
||
return show_msg('Неверный номер месяца', 'Укажите число в диапазоне 1-12', level='warn')
|
||
birth_y = int(b.get_object('birth_year').get_text())
|
||
except ValueError:
|
||
return show_msg('Неверно указана дата рождения', 'Все поля даты должны быть заполнены', level='warn')
|
||
gender = b.get_object('gender').get_active_id()
|
||
if not gender:
|
||
return show_msg('Не выбран пол', level='warn')
|
||
birth_date = date(birth_y, birth_m, birth_d)
|
||
with db.atomic():
|
||
try:
|
||
patient = Patient.create(
|
||
last_name=l_name,
|
||
first_name=f_name,
|
||
middle_name=m_name,
|
||
birth_date=birth_date,
|
||
gender=gender
|
||
)
|
||
except peewee.IntegrityError:
|
||
return show_msg('Данный пациент уже существует', 'Пациент с указанными фамилией, именем\nи датой рождения уже есть с базе данных', level='warn')
|
||
store_patient_index(patient)
|
||
row = build_patient_row(patient)
|
||
patient_list.add(row)
|
||
patient_list.select_row(row)
|
||
patient_list.show_all()
|
||
b.get_object('new_patient_window').close()
|
||
b.add_from_file(new_patient_win_file)
|
||
b.connect_signals(NewPatienWinHandler())
|
||
w = b.get_object('new_patient_window')
|
||
return w
|
||
|
||
main_win = builder.get_object('main_window')
|
||
main_win.show_all()
|
||
Gtk.main()
|