/*******************************************************************************
Ø * Copyright (c) 2012 MEDEVIT <office@medevit.at>.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* MEDEVIT <office@medevit.at> - initial API and implementation
******************************************************************************/
package ch.elexis.core.ui.contacts.views;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.beans.PojoObservables;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.forms.events.ExpansionAdapter;
import org.eclipse.ui.forms.events.ExpansionEvent;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.forms.widgets.TableWrapData;
import org.eclipse.ui.forms.widgets.TableWrapLayout;
import org.eclipse.ui.part.ViewPart;
import ch.elexis.admin.AccessControlDefaults;
import ch.elexis.core.constants.StringConstants;
import ch.elexis.core.data.activator.CoreHub;
import ch.elexis.core.data.events.ElexisEvent;
import ch.elexis.core.data.events.ElexisEventDispatcher;
import ch.elexis.core.data.events.ElexisEventListener;
import ch.elexis.core.model.IPersistentObject;
import ch.elexis.core.ui.actions.GlobalActions;
import ch.elexis.core.ui.actions.RestrictedAction;
import ch.elexis.core.ui.contacts.dialogs.BezugsKontaktAuswahl;
import ch.elexis.core.ui.dialogs.KontaktDetailDialog;
import ch.elexis.core.ui.dialogs.KontaktSelektor;
import ch.elexis.core.ui.dialogs.ZusatzAdresseEingabeDialog;
import ch.elexis.core.ui.events.ElexisUiEventListenerImpl;
import ch.elexis.core.ui.locks.IUnlockable;
import ch.elexis.core.ui.locks.ToggleCurrentPatientLockHandler;
import ch.elexis.core.ui.medication.views.FixMediDisplay;
import ch.elexis.core.ui.util.ListDisplay;
import ch.elexis.core.ui.util.ViewMenus;
import ch.elexis.core.ui.util.WidgetFactory;
import ch.elexis.core.ui.views.Messages;
import ch.elexis.core.ui.views.controls.ClientCustomTextComposite;
import ch.elexis.core.ui.views.controls.StickerComposite;
import ch.elexis.data.BezugsKontakt;
import ch.elexis.data.Kontakt;
import ch.elexis.data.Patient;
import ch.elexis.data.Person;
import ch.elexis.data.ZusatzAdresse;
import ch.rgw.tools.StringTool;
public class PatientDetailView extends ViewPart implements IUnlockable {
public static final String ID = "at.medevit.elexis.contacts.views.PatientDetail"; //$NON-NLS-1$
private final FormToolkit toolkit = new FormToolkit(Display.getCurrent());
private final static String FIXMEDIKATION = Messages.Patientenblatt2_fixmedication;
private static final String KEY_PATIENTENBLATT = "PatientenDetailView/"; //$NON-NLS-1$
private ScrolledForm scrldfrm;
private ViewMenus viewmenu;
private Text txtDiagnosen;
private Text txtAnamnese;
private Text txtFamAnamnese;
private Text txtAllergien;
private Text txtRisiken;
private Text txtBemerkungen;
private ClientCustomTextComposite compClientCustomText;
private StickerComposite stickerComposite;
private IAction removeZAAction, showZAAction, removeAdditionalAddressAction,
showAdditionalAddressAction;
private ListDisplay<BezugsKontakt> inpZusatzAdresse;
private ListDisplay<ZusatzAdresse> additionalAddresses;
private IObservableValue patientObservable = new WritableValue(null, Patient.class);
private ElexisEventListener eeli_pat = new ElexisUiEventListenerImpl(Patient.class) {
public void runInUi(ElexisEvent ev) {
Patient pat = (Patient) ev.getObject();
switch (ev.getType()) {
case ElexisEvent.EVENT_SELECTED:
IPersistentObject deselected = (IPersistentObject) patientObservable.getValue();
setPatient(pat);
releaseAndRefreshLock(deselected, ToggleCurrentPatientLockHandler.COMMAND_ID);
break;
case ElexisEvent.EVENT_LOCK_AQUIRED:
case ElexisEvent.EVENT_LOCK_RELEASED:
if (pat.equals(patientObservable.getValue())) {
setUnlocked(ev.getType() == ElexisEvent.EVENT_LOCK_AQUIRED);
}
break;
default:
break;
}
}
};
private void releaseAndRefreshLock(IPersistentObject object, String commandId){
if (object != null && CoreHub.getLocalLockService().isLockedLocal(object)) {
CoreHub.getLocalLockService().releaseLock(object);
}
ICommandService commandService =
(ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class);
commandService.refreshElements(commandId, null);
}
private FixMediDisplay dmd;
public PatientDetailView() {
toolkit.setBorderStyle(SWT.NULL); // Deactivate borders for the widgets
makeActions();
ElexisEventDispatcher.getInstance().addListeners(eeli_pat);
}
@Override
public void setUnlocked(boolean unlocked) {
txtDiagnosen.setEditable(unlocked);
txtAnamnese.setEditable(unlocked);
txtFamAnamnese.setEditable(unlocked);
txtAllergien.setEditable(unlocked);
txtRisiken.setEditable(unlocked);
txtBemerkungen.setEditable(unlocked);
dmd.setUnlocked(false); // https://redmine.medelexis.ch/issues/4602
inpZusatzAdresse.setUnlocked(unlocked);
}
void setPatient(Patient p) {
patientObservable.setValue(p);
scrldfrm.setText(StringTool.unNull(p.getName()) + StringConstants.SPACE + StringTool.unNull(p.getVorname())
+ " (" + p.getPatCode() + ")");
compClientCustomText.updateClientCustomArea();
stickerComposite.setPatient(p);
inpZusatzAdresse.clear();
for (BezugsKontakt za : p.getBezugsKontakte()) {
inpZusatzAdresse.add(za);
}
additionalAddresses.clear();
for (ZusatzAdresse zusatzAdresse : p.getZusatzAdressen()) {
additionalAddresses.add(zusatzAdresse);
}
dmd.reload();
scrldfrm.reflow(true);
setUnlocked(CoreHub.getLocalLockService().isLockedLocal(p));
}
/**
* Create contents of the view part.
*
* @param parent
*/
@Override
public void createPartControl(Composite parent) {
// getSite().getPage().addSelectionListener(patientSelectionListener);
parent.setLayout(new GridLayout(1, false));
scrldfrm = toolkit.createScrolledForm(parent);
scrldfrm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
TableWrapLayout td = new TableWrapLayout();
scrldfrm.setText(Messages.Patientenblatt2_noPatientSelected);
scrldfrm.getBody().setLayout(td);
Composite scrldfrmComposite = scrldfrm.getBody();
// custom area for user
{
compClientCustomText = new ClientCustomTextComposite(scrldfrm.getBody(), SWT.None, toolkit, scrldfrm);
}
// sticker composite
{
stickerComposite = new StickerComposite(scrldfrm.getBody(), SWT.NONE, toolkit);
}
// bezugs kontakte
{
ExpandableComposite ecZA = WidgetFactory.createExpandableComposite(toolkit, scrldfrm,
Messages.Patientenblatt2_additionalAdresses); // $NON-NLS-1$
ecZA.setExpanded(CoreHub.localCfg.get(KEY_PATIENTENBLATT + ecZA.getText(), false));
ecZA.addExpansionListener(new SectionExpansionHandler());
inpZusatzAdresse = new ListDisplay<BezugsKontakt>(ecZA, SWT.NONE, new ListDisplay.LDListener() {
/*
* public boolean dropped(final PersistentObject dropped) {
* return false; }
*/
public void hyperlinkActivated(final String l) {
Patient sp = ElexisEventDispatcher.getSelectedPatient();
if (sp == null) {
return;
}
final String[] sortFields = new String[] { Kontakt.FLD_NAME1, Kontakt.FLD_NAME2,
Kontakt.FLD_STREET };
KontaktSelektor ksl = new KontaktSelektor(PlatformUI.getWorkbench().getDisplay().getActiveShell(),
Kontakt.class, Messages.Patientenblatt2_contactForAdditionalAddress,
Messages.Patientenblatt2_pleaseSelectardress, sortFields); // $NON-NLS-1$
// //$NON-NLS-2$
if (ksl.open() == Dialog.OK) {
Kontakt k = (Kontakt) ksl.getSelection();
if (k != null) {
BezugsKontaktAuswahl bza =
new BezugsKontaktAuswahl(sp.getLabel(true),
k.istPerson() ? Person.load(k.getId()).getLabel(true)
: k.getLabel(true));
if (bza.open() == Dialog.OK && sp != null) {
BezugsKontakt bk =
sp.addBezugsKontakt(k, bza.getBezugKonkaktRelation());
inpZusatzAdresse.add(bk);
scrldfrm.reflow(true);
}
}
}
}
public String getLabel(Object o) {
BezugsKontakt bezugsKontakt = (BezugsKontakt) o;
StringBuffer sb = new StringBuffer();
sb.append(bezugsKontakt.getLabel());
Kontakt other = Kontakt.load(bezugsKontakt.get(BezugsKontakt.OTHER_ID));
if (other.exists()) {
List<String> tokens = new ArrayList<String>();
String telefon1 = other.get(Kontakt.FLD_PHONE1);
String telefon2 = other.get(Kontakt.FLD_PHONE2);
String mobile = other.get(Kontakt.FLD_MOBILEPHONE);
String eMail = other.get(Kontakt.FLD_E_MAIL);
String fax = other.get(Kontakt.FLD_FAX);
if (!StringTool.isNothing(telefon1)) {
tokens.add("T1: " + telefon1); //$NON-NLS-1$
}
if (!StringTool.isNothing(telefon2)) {
tokens.add("T2: " + telefon2); //$NON-NLS-1$
}
if (!StringTool.isNothing(mobile)) {
tokens.add("M: " + mobile); //$NON-NLS-1$
}
if (!StringTool.isNothing(fax)) {
tokens.add("F: " + fax); //$NON-NLS-1$
}
if (!StringTool.isNothing(eMail)) {
tokens.add(eMail);
}
for (String token : tokens) {
sb.append(", "); //$NON-NLS-1$
sb.append(token);
}
return sb.toString();
}
return "?"; //$NON-NLS-1$
}
});
inpZusatzAdresse.addHyperlinks(Messages.Patientenblatt2_add); // $NON-NLS-1$
// inpZusatzAdresse.setMenu(createZusatzAdressMenu());
inpZusatzAdresse.setMenu(removeZAAction, showZAAction);
ecZA.setClient(inpZusatzAdresse);
}
// zusatz adressen
{
ExpandableComposite compAdditionalAddresses =
WidgetFactory.createExpandableComposite(toolkit, scrldfrm,
"Zusatzadressen"); // $NON-NLS-1$
compAdditionalAddresses.addExpansionListener(new SectionExpansionHandler());
additionalAddresses = new ListDisplay<ZusatzAdresse>(compAdditionalAddresses, SWT.NONE,
new ListDisplay.LDListener() {
public void hyperlinkActivated(final String l){
Patient actPatient = ElexisEventDispatcher.getSelectedPatient();
if (actPatient != null) {
ZusatzAdresseEingabeDialog aed =
new ZusatzAdresseEingabeDialog(
PlatformUI.getWorkbench().getDisplay().getActiveShell(),
actPatient);
if (aed.open() == Dialog.OK) {
additionalAddresses.add(aed.getZusatzAdresse());
scrldfrm.reflow(true);
}
}
}
public String getLabel(Object o){
ZusatzAdresse address = (ZusatzAdresse) o;
if (address != null) {
return address.getLabel();
}
return "?"; //$NON-NLS-1$
}
});
// Hyperlink "Hinzu..." über der Adressliste hinzufügen
additionalAddresses.addHyperlinks(Messages.Patientenblatt2_add); // $NON-NLS-1$
// Das Kontext-Menü jedes Eintrags in der Adressliste erzeugen
// inpZusatzAdresse.setMenu(createZusatzAdressMenu());
makeAdditionalAddressActions();
additionalAddresses.setMenu(removeAdditionalAddressAction, showAdditionalAddressAction);
compAdditionalAddresses.setClient(additionalAddresses);
}
// diagnosis
{
Section sectDiagnosen = toolkit.createSection(scrldfrmComposite, Section.EXPANDED | Section.TWISTIE);
TableWrapData twd_sectDiagnosen = new TableWrapData(TableWrapData.LEFT, TableWrapData.TOP, 1, 1);
twd_sectDiagnosen.grabHorizontal = true;
twd_sectDiagnosen.valign = TableWrapData.FILL;
twd_sectDiagnosen.align = TableWrapData.FILL;
sectDiagnosen.setLayoutData(twd_sectDiagnosen);
sectDiagnosen.setText("Diagnosen");
sectDiagnosen.setExpanded(CoreHub.localCfg.get(KEY_PATIENTENBLATT + sectDiagnosen.getText(), false));
txtDiagnosen = toolkit.createText(sectDiagnosen, "", SWT.WRAP | SWT.MULTI);
txtDiagnosen.addListener(SWT.Modify, new MultiLineAutoGrowListener(txtDiagnosen));
sectDiagnosen.setClient(txtDiagnosen);
sectDiagnosen.addExpansionListener(new SectionExpansionHandler());
}
// personal anamnesis
{
Section sectAnamnese = toolkit.createSection(scrldfrmComposite, Section.EXPANDED | Section.TWISTIE);
TableWrapData twd_sectDiagnosen = new TableWrapData(TableWrapData.LEFT, TableWrapData.TOP, 1, 1);
twd_sectDiagnosen.grabHorizontal = true;
twd_sectDiagnosen.align = TableWrapData.FILL;
sectAnamnese.setLayoutData(twd_sectDiagnosen);
sectAnamnese.setText("Persönliche Anamnese");
sectAnamnese.setExpanded(CoreHub.localCfg.get(KEY_PATIENTENBLATT + sectAnamnese.getText(), false));
txtAnamnese = toolkit.createText(sectAnamnese, "", SWT.WRAP | SWT.MULTI);
txtAnamnese.addListener(SWT.Modify, new MultiLineAutoGrowListener(txtAnamnese));
sectAnamnese.setClient(txtAnamnese);
sectAnamnese.addExpansionListener(new SectionExpansionHandler());
}
// family anamnesis
{
Section sectFamAnamnese = toolkit.createSection(scrldfrmComposite, Section.EXPANDED | Section.TWISTIE);
TableWrapData twd_sectDiagnosen = new TableWrapData(TableWrapData.LEFT, TableWrapData.TOP, 1, 1);
twd_sectDiagnosen.grabHorizontal = true;
twd_sectDiagnosen.align = TableWrapData.FILL;
sectFamAnamnese.setLayoutData(twd_sectDiagnosen);
sectFamAnamnese.setText("Familien-Anamnese");
sectFamAnamnese.setExpanded(CoreHub.localCfg.get(KEY_PATIENTENBLATT + sectFamAnamnese.getText(), false));
txtFamAnamnese = toolkit.createText(sectFamAnamnese, "", SWT.WRAP | SWT.MULTI);
txtFamAnamnese.setText("");
txtFamAnamnese.addListener(SWT.Modify, new MultiLineAutoGrowListener(txtFamAnamnese));
sectFamAnamnese.setClient(txtFamAnamnese);
sectFamAnamnese.addExpansionListener(new SectionExpansionHandler());
}
// allergy
{
Section sectAllergien = toolkit.createSection(scrldfrmComposite, Section.EXPANDED | Section.TWISTIE);
TableWrapData twd_sectDiagnosen = new TableWrapData(TableWrapData.LEFT, TableWrapData.TOP, 1, 1);
twd_sectDiagnosen.grabHorizontal = true;
twd_sectDiagnosen.align = TableWrapData.FILL;
sectAllergien.setLayoutData(twd_sectDiagnosen);
sectAllergien.setText("Allergien");
sectAllergien.setExpanded(CoreHub.localCfg.get(KEY_PATIENTENBLATT + sectAllergien.getText(), false));
txtAllergien = toolkit.createText(sectAllergien, "", SWT.WRAP | SWT.MULTI);
txtAllergien.setText("");
txtAllergien.addListener(SWT.Modify, new MultiLineAutoGrowListener(txtAllergien));
sectAllergien.setClient(txtAllergien);
sectAllergien.addExpansionListener(new SectionExpansionHandler());
}
// risks
{
Section sectRisiken = toolkit.createSection(scrldfrmComposite, Section.EXPANDED | Section.TWISTIE);
TableWrapData twd_sectDiagnosen = new TableWrapData(TableWrapData.LEFT, TableWrapData.TOP, 1, 1);
twd_sectDiagnosen.grabHorizontal = true;
twd_sectDiagnosen.align = TableWrapData.FILL;
sectRisiken.setLayoutData(twd_sectDiagnosen);
sectRisiken.setText("Risiken");
sectRisiken.setExpanded(CoreHub.localCfg.get(KEY_PATIENTENBLATT + sectRisiken.getText(), false));
txtRisiken = toolkit.createText(sectRisiken, "", SWT.WRAP | SWT.MULTI);
txtRisiken.setText("");
txtRisiken.addListener(SWT.Modify, new MultiLineAutoGrowListener(txtRisiken));
sectRisiken.setClient(txtRisiken);
sectRisiken.addExpansionListener(new SectionExpansionHandler());
}
// remarks
{
Section sectBemerkungen = toolkit.createSection(scrldfrmComposite, Section.EXPANDED | Section.TWISTIE);
TableWrapData twd_sectDiagnosen = new TableWrapData(TableWrapData.LEFT, TableWrapData.TOP, 1, 1);
twd_sectDiagnosen.grabHorizontal = true;
twd_sectDiagnosen.align = TableWrapData.FILL;
sectBemerkungen.setLayoutData(twd_sectDiagnosen);
sectBemerkungen.setText("Bemerkungen");
sectBemerkungen.setExpanded(CoreHub.localCfg.get(KEY_PATIENTENBLATT + sectBemerkungen.getText(), false));
txtBemerkungen = toolkit.createText(sectBemerkungen, "", SWT.WRAP | SWT.MULTI);
txtBemerkungen.setText("");
txtBemerkungen.addListener(SWT.Modify, new MultiLineAutoGrowListener(txtBemerkungen));
sectBemerkungen.setClient(txtBemerkungen);
sectBemerkungen.addExpansionListener(new SectionExpansionHandler());
}
{
ExpandableComposite ecdm = WidgetFactory.createExpandableComposite(toolkit, scrldfrm, FIXMEDIKATION);
ecdm.addExpansionListener(new SectionExpansionHandler());
dmd = new FixMediDisplay(ecdm, getViewSite());
ecdm.setClient(dmd);
}
viewmenu = new ViewMenus(getViewSite());
viewmenu.createMenu(GlobalActions.printEtikette, GlobalActions.printAdresse, GlobalActions.printBlatt,
GlobalActions.printRoeBlatt);
initDataBindings();
}
public void dispose() {
ElexisEventDispatcher.getInstance().removeListeners(eeli_pat);
toolkit.dispose();
super.dispose();
}
@Override
public void setFocus() {
// COMPAT
// Initialize the current patient if view is about to be opened and no
// selection yet
if (patientObservable.getValue() == null) {
Patient p = ElexisEventDispatcher.getSelectedPatient();
if (p != null)
setPatient(p);
}
}
/**
* This {@link Listener} automatically grows and shrinks a {@link Text}
* according to the number of lines contained. It handles {@link SWT#Modify}
* events only.
*
* @see http://stackoverflow.com/questions/8287853/text-widget-with-self-
* adjusting-height-based-on-interactively-entered-text
*
*/
private final class MultiLineAutoGrowListener implements Listener {
protected int lines = 0;
private Text t;
public MultiLineAutoGrowListener(Text t) {
this.t = t;
}
@Override
public void handleEvent(Event event) {
if (event.type != SWT.Modify)
return;
if (t.getLineCount() != lines) {
lines = t.getLineCount();
t.setSize(t.getSize().x, lines * (int) t.getFont().getFontData()[0].height);
scrldfrm.reflow(true);
}
}
}
/**
* Handle section expansion events by advising the form composite to reflow
* itself.
*/
private final class SectionExpansionHandler extends ExpansionAdapter {
@Override
public void expansionStateChanged(ExpansionEvent e) {
ExpandableComposite src = (ExpandableComposite) e.getSource();
CoreHub.localCfg.set(KEY_PATIENTENBLATT + src.getText(), src.isExpanded());
scrldfrm.reflow(true);
}
}
protected void initDataBindings() {
DataBindingContext bindingContext = new DataBindingContext();
Text[] control = { txtAllergien, txtAnamnese, txtBemerkungen, txtDiagnosen, txtRisiken, txtFamAnamnese };
String[] property = { "allergies", "personalAnamnese", "comment", "diagnosen", "risk", "familyAnamnese" };
for (int i = 0; i < control.length; i++) {
bindValue(control[i], property[i], bindingContext);
}
}
private void bindValue(Text text, String property, DataBindingContext bindingContext) {
IObservableValue textObserveWidget = SWTObservables.observeDelayedValue(5,
SWTObservables.observeText(text, SWT.Modify));
IObservableValue observeValue = PojoObservables.observeDetailValue(patientObservable, property, String.class);
bindingContext.bindValue(textObserveWidget, observeValue, null, null);
}
private void makeActions() {
removeZAAction = new Action(Messages.Patientenblatt2_removeAddress) {
@Override
public void run() {
BezugsKontakt a = (BezugsKontakt) inpZusatzAdresse.getSelection();
a.delete();
setPatient(ElexisEventDispatcher.getSelectedPatient());
}
};
showZAAction = new RestrictedAction(AccessControlDefaults.PATIENT_DISPLAY,
Messages.Patientenblatt2_showAddress) {
@Override
public void doRun() {
Kontakt a = Kontakt.load(((BezugsKontakt) inpZusatzAdresse.getSelection()).get(BezugsKontakt.OTHER_ID));
KontaktDetailDialog kdd = new KontaktDetailDialog(scrldfrm.getShell(), a);
kdd.open();
}
};
}
private void makeAdditionalAddressActions(){
removeAdditionalAddressAction = new Action(Messages.Patientenblatt2_removeAddress) {
@Override
public void run(){
ZusatzAdresse a = (ZusatzAdresse) additionalAddresses.getSelection();
a.delete();
setPatient(ElexisEventDispatcher.getSelectedPatient());
}
};
showAdditionalAddressAction = new Action(Messages.Patientenblatt2_showAddress) {
@Override
public void run(){
Patient actPatient = ElexisEventDispatcher.getSelectedPatient();
ZusatzAdresse zusatzAdresse = (ZusatzAdresse) additionalAddresses.getSelection();
ZusatzAdresseEingabeDialog aed =
new ZusatzAdresseEingabeDialog(scrldfrm.getShell(), actPatient, zusatzAdresse);
if (aed.open() == Dialog.OK) {
setPatient(actPatient);
}
}
};
}
}