ch.elexis.dialogs.TerminDialog.java Source code

Java tutorial

Introduction

Here is the source code for ch.elexis.dialogs.TerminDialog.java

Source

/*******************************************************************************
 * Copyright (c) 2006-2010, G. Weirich and Elexis
 * 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:
 *    G. Weirich - initial implementation, adapted from JavaAgenda
 *    
 *******************************************************************************/

package ch.elexis.dialogs;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Hashtable;

import org.apache.commons.lang.StringUtils;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.events.HyperlinkAdapter;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.widgets.Hyperlink;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.tiff.common.ui.datepicker.DatePicker;

import ch.elexis.actions.Activator;
import ch.elexis.agenda.Messages;
import ch.elexis.agenda.acl.ACLContributor;
import ch.elexis.agenda.data.IPlannable;
import ch.elexis.agenda.data.Termin;
import ch.elexis.agenda.data.Termin.Free;
import ch.elexis.agenda.preferences.PreferenceConstants;
import ch.elexis.agenda.util.Plannables;
import ch.elexis.agenda.util.TimeInput;
import ch.elexis.agenda.util.TimeInput.TimeInputListener;
import ch.elexis.core.constants.Preferences;
import ch.elexis.core.data.activator.CoreHub;
import ch.elexis.core.data.events.ElexisEventDispatcher;
import ch.elexis.core.jdt.NonNull;
import ch.elexis.core.ui.UiDesk;
import ch.elexis.core.ui.dialogs.KontaktSelektor;
import ch.elexis.core.ui.icons.Images;
import ch.elexis.core.ui.locks.AcquireLockBlockingUi;
import ch.elexis.core.ui.locks.ILockHandler;
import ch.elexis.core.ui.util.NumberInput;
import ch.elexis.core.ui.util.SWTHelper;
import ch.elexis.data.Kontakt;
import ch.elexis.data.Patient;
import ch.elexis.data.Query;
import ch.elexis.data.User;
import ch.rgw.tools.StringTool;
import ch.rgw.tools.TimeSpan;
import ch.rgw.tools.TimeTool;

/**
 * Dialog zur Eingabe eines oder mehrerer Termine in die Agenda.
 * 
 * @author gerry
 * 
 */
public class TerminDialog extends TitleAreaDialog {

    private static final Logger log = LoggerFactory.getLogger(TerminDialog.class);

    DatePicker dp;
    TimeInput tiVon;
    TimeInput tiBis;
    int ts = CoreHub.userCfg.get("agenda/dayView/Start", 7); //$NON-NLS-1$
    int te = CoreHub.userCfg.get("agenda/dayView/End", 19); //$NON-NLS-1$
    int tagStart = ts * 60; // 7 Uhr
    int tagEnd = te * 60;
    int[] rasterValues = new int[] { 5, 10, 15, 30 };
    int rasterIndex = CoreHub.userCfg.get("agenda/dayView/raster", 3); //$NON-NLS-1$
    Hashtable<String, String> tMap;
    double minutes;
    double pixelPerMinute;

    NumberInput niDauer;
    ArrayList<Termin> lTermine;
    List lTerminListe;
    // Button bPrev,bNext;
    Button bLocked, bSerie;
    Button bSave, bDelete, bChange, bPrint, bFuture, bEmergency;
    Slider slider;
    DayOverview dayBar;

    Kontakt actKontakt;
    IPlannable actPlannable;
    // TagesView base;
    // String[] bereiche;
    Text tNr, tName, tBem;
    Combo cbTyp, cbStatus, cbMandant;
    Text tGrund;
    Activator agenda = Activator.getDefault();
    boolean bModified;
    private String msg;

    public TerminDialog(IPlannable act) {
        super(UiDesk.getTopShell());
        // base=parent;
        if (act == null) {
            act = new Termin.Free(agenda.getActDate().toString(TimeTool.DATE_COMPACT), 0, 30);
        }
        if (act instanceof Termin) {
            Termin lact = (Termin) act;
            actKontakt = lact.getKontakt();
        } else {
            actKontakt = ElexisEventDispatcher.getSelectedPatient();
        }
        Color green = UiDesk.getColor(UiDesk.COL_GREEN);
        if (green == null) {
            UiDesk.getColorRegistry().put(UiDesk.COL_GREEN, new RGB(0, 255, 0));
        }
        actPlannable = act;
        tMap = Plannables.getTimePrefFor(agenda.getActResource());
        tMap.put(Termin.typFrei(), "0"); //$NON-NLS-1$
        tMap.put(Termin.typReserviert(), "0"); //$NON-NLS-1$
    }

    /**
     * Use this constructor for creating a new {@link Termin} from a date and for a resource.
     * 
     * @param date
     * @param resource
     * @param patient
     */
    public TerminDialog(@NonNull TimeTool date, @NonNull String resource, Patient patient) {
        super(UiDesk.getTopShell());
        Free act = new Termin.Free(date.toString(TimeTool.DATE_COMPACT),
                date.get(TimeTool.HOUR_OF_DAY) * 60 + date.get(TimeTool.MINUTE), 30);
        actKontakt = patient;
        Color green = UiDesk.getColor(UiDesk.COL_GREEN);
        if (green == null) {
            UiDesk.getColorRegistry().put(UiDesk.COL_GREEN, new RGB(0, 255, 0));
        }
        actPlannable = act;
        agenda.setActResource(resource);
        tMap = Plannables.getTimePrefFor(agenda.getActResource());
        tMap.put(Termin.typFrei(), "0"); //$NON-NLS-1$
        tMap.put(Termin.typReserviert(), "0"); //$NON-NLS-1$
    }

    public static void setActResource(String resource) {
        Activator.getDefault().setActResource(resource);
    }

    @Override
    protected Control createDialogArea(final Composite parent) {
        ScrolledComposite sc = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL);
        sc.setLayoutData(SWTHelper.getFillGridData(1, true, 1, true));
        Composite ret = new Composite(sc, SWT.NONE);
        sc.setContent(ret);
        // ret.setLayoutData(SWTHelper.getFillGridData(1, true, 1, true));
        ret.setLayout(new GridLayout());
        Composite topRow = new Composite(ret, SWT.BORDER);
        topRow.setLayoutData(SWTHelper.getFillGridData(1, true, 1, false));
        topRow.setLayout(new GridLayout(3, true));
        // oben links
        dp = new DatePicker(topRow, SWT.NONE);
        dp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
        dp.setDate(agenda.getActDate().getTime());
        // actDate.setTime(dp.getDate());
        dp.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent e) {
                // actDate.setTime(dp.getDate());
                agenda.setActDate(new TimeTool(dp.getDate().getTime()));
                dayBar.redraw();
                slider.set();
            }

        });
        // oben mitte
        Composite topCenter = new Composite(topRow, SWT.NONE);
        topCenter.setLayout(new GridLayout(3, true));
        topCenter.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));
        tiVon = new TimeInput(topCenter, Messages.TerminDialog_startTime);
        tiVon.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
        tiVon.addListener(new TimeInputListener() {
            public void changed() {
                slider.set();
            }

        });
        niDauer = new NumberInput(topCenter, Messages.TerminDialog_duration);
        niDauer.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
        niDauer.getControl().addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent e) {
                slider.set();
            }
        });
        tiBis = new TimeInput(topCenter, Messages.TerminDialog_endTime);
        tiBis.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
        tiBis.addListener(new TimeInputListener() {
            public void changed() {
                int mVon = tiVon.getTimeAsMinutes();
                int mBis = tiBis.getTimeAsMinutes();
                niDauer.setValue(mBis - mVon);
                slider.set();
            }
        });
        lTermine = new ArrayList<Termin>();
        lTerminListe = new List(topCenter, SWT.BORDER | SWT.SINGLE | SWT.V_SCROLL | SWT.H_SCROLL);
        lTerminListe.setLayoutData(SWTHelper.getFillGridData(3, true, 1, true));
        lTerminListe.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(final SelectionEvent e) {
                int idx = lTerminListe.getSelectionIndex();
                if ((idx > -1) && (idx < lTermine.size())) {
                    actPlannable = lTermine.get(idx);
                    setAll();
                }
            }

        });

        // oben rechts
        Composite topRight = new Composite(topRow, SWT.NONE);
        topRight.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
        topRight.setLayout(new GridLayout(2, true));
        Label sep = new Label(topRight, SWT.NONE);
        sep.setText(" "); //$NON-NLS-1$
        sep.setLayoutData(SWTHelper.getFillGridData(2, false, 1, false));
        /*
         * bPrev=new Button(topRight,SWT.PUSH); bPrev.setText("<--"); //$NON-NLS-1$
         * bPrev.setToolTipText(Messages.TerminDialog_earlier); bNext=new Button(topRight,SWT.PUSH);
         * bNext.setText("-->"); //$NON-NLS-1$ bNext.setToolTipText(Messages.TerminDialog_later);
         */
        bLocked = new Button(topRight, SWT.CHECK);
        bLocked.setText(Messages.TerminDialog_locked);
        bLocked.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent e) {
                if (actPlannable instanceof Termin) {
                    ((Termin) actPlannable).setLocked(bLocked.getSelection());
                }
                setEnablement();
            }
        });
        if (CoreHub.acl.request(ACLContributor.CHANGE_APPLOCK) == false) {
            bLocked.setEnabled(false);
        }
        bSerie = new Button(topRight, SWT.CHECK);
        bSerie.setText(Messages.TerminDialog_serie);
        bSave = new Button(topRight, SWT.PUSH);
        bSave.setText(Messages.TerminDialog_set);
        bSave.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
        bSave.setToolTipText(Messages.TerminDialog_createTermin);
        bSave.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent e) {
                createTermin(true);
            }
        });
        Point s = bSave.computeSize(SWT.DEFAULT, SWT.DEFAULT);
        bChange = new Button(topRight, SWT.PUSH);
        bChange.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
        bChange.setText(Messages.TerminDialog_change);
        bChange.setToolTipText(Messages.TerminDialog_changeTermin);
        bDelete = new Button(topRight, SWT.PUSH);
        bDelete.setText(Messages.TerminDialog_delete);
        bDelete.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
        bDelete.setToolTipText(Messages.TerminDialog_deleteTermin);
        bDelete.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent e) {
                if (actPlannable instanceof Termin) {
                    lTerminListe.remove(lTerminListe.getSelectionIndex());
                    lTermine.remove(actPlannable);
                    ((Termin) actPlannable).delete();
                    ElexisEventDispatcher.reload(Termin.class);
                    dayBar.recalc();
                    setEnablement();
                }
                super.widgetSelected(e);
            }

        });
        Button bSearch = new Button(topRight, SWT.PUSH);
        bSearch.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
        bSearch.setText(Messages.TerminDialog_find);

        bSearch.setToolTipText(Messages.TerminDialog_findTermin);
        bSearch.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(final SelectionEvent e) {
                if (actKontakt != null) {
                    Query<Termin> qbe = new Query<Termin>(Termin.class);
                    qbe.add("Wer", "=", actKontakt.getId());
                    qbe.add("deleted", "<>", "1");
                    if (bFuture.getSelection() == false) {
                        qbe.add("Tag", ">", new TimeTool().toString(TimeTool.DATE_COMPACT));
                    }
                    java.util.List<Termin> list = qbe.execute();
                    list.sort(new Comparator<Termin>() {
                        @Override
                        public int compare(Termin t1, Termin t2) {
                            return t2.getStartTime().compareTo(t1.getStartTime());
                        }
                    });
                    lTermine.clear();
                    lTerminListe.removeAll();
                    if ((list != null) && (list.size() > 0)) {
                        for (Termin t : list) {
                            lTermine.add(t);
                            String label = t.getLabel();
                            log.info(label);
                            lTerminListe.add(label);
                        }
                        lTerminListe.select(0);
                    }
                }
            }

        });
        bPrint = new Button(topRight, SWT.PUSH);
        bPrint.setText(Messages.TerminDialog_print);
        bPrint.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
        bPrint.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent e) {
                new TermineDruckenDialog(getShell(), lTermine.toArray(new Termin[0])).open();
            }

        });
        bFuture = new Button(topRight, SWT.CHECK);
        bFuture.setText(Messages.TerminDialog_past);

        bEmergency = new Button(topRight, SWT.CHECK);
        bEmergency.setText(Messages.TerminDialog_emergency);

        // Balken
        Composite cBar = new Composite(ret, SWT.BORDER);
        cBar.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
        cBar.setLayout(new GridLayout());
        dayBar = new DayOverview(cBar);
        dayBar.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
        slider = new Slider(dayBar);

        // unten
        Composite cBottom = new Composite(ret, SWT.BORDER);
        cBottom.setLayout(new GridLayout(3, false));
        cBottom.setLayoutData(SWTHelper.getFillGridData(1, true, 1, true));

        // Zeile 1
        new Label(cBottom, SWT.NONE).setText("PatientID"); //$NON-NLS-1$
        Composite cLinks = new Composite(cBottom, SWT.NONE);
        cLinks.setLayout(new RowLayout(SWT.HORIZONTAL));
        new Label(cLinks, SWT.NONE).setText("Personalien ");

        Hyperlink hlText = new Hyperlink(cLinks, SWT.NONE);
        hlText.setText(Messages.TerminDialog_enterPersonalia);
        hlText.addHyperlinkListener(new HyperlinkAdapter() {
            @Override
            public void linkActivated(final HyperlinkEvent e) {
                InputDialog inp = new InputDialog(getShell(), Messages.TerminDialog_enterText,
                        Messages.TerminDialog_enterFreeText, "", null); //$NON-NLS-1$
                if (inp.open() == Dialog.OK) {
                    tName.setText(inp.getValue());
                    tNr.setText(""); //$NON-NLS-1$
                    actKontakt = null;
                }
            }
        });
        hlText.setForeground(UiDesk.getColor(UiDesk.COL_BLUE));
        // new Label(cLinks,SWT.SEPARATOR|SWT.VERTICAL);
        Hyperlink hlSelect = new Hyperlink(cLinks, SWT.NONE);
        hlSelect.setForeground(UiDesk.getColor(UiDesk.COL_BLUE));
        hlSelect.setText("(Kontakt auswhlen)");
        hlSelect.addHyperlinkListener(new HyperlinkAdapter() {
            @Override
            public void linkActivated(final HyperlinkEvent e) {
                KontaktSelektor ksl = new KontaktSelektor(getShell(), Kontakt.class, "Termin zuordnen",
                        "Bitte suchen Sie aus, wer den Termin hat", Kontakt.DEFAULT_SORT);
                if (ksl.open() == Dialog.OK) {
                    actKontakt = (Kontakt) ksl.getSelection();
                    if (actKontakt != null) {
                        tName.setText(actKontakt.getLabel());
                        tNr.setText(actKontakt.get(Kontakt.FLD_SHORT_LABEL));
                    }
                    setEnablement();
                }
            }
        });

        new Label(cBottom, SWT.NONE).setText(Messages.TerminDialog_Mandator);
        // Zeile 2
        tNr = new Text(cBottom, SWT.BORDER | SWT.READ_ONLY);
        tName = new Text(cBottom, SWT.BORDER | SWT.READ_ONLY);
        tName.setLayoutData(SWTHelper.getFillGridData(1, true, 1, false));
        cbMandant = new Combo(cBottom, SWT.SINGLE);
        cbMandant.setItems(agenda.getResources());
        cbMandant.setText(agenda.getActResource());
        cbMandant.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent e) {
                setAll();
            }

        });
        // Zeile 3
        Label lBem = new Label(cBottom, SWT.NONE);
        lBem.setText(Messages.TerminDialog_remarks);
        lBem.setLayoutData(SWTHelper.getFillGridData(3, false, 1, false));
        // Zeile 4
        tBem = new Text(cBottom, SWT.BORDER | SWT.READ_ONLY);
        tBem.setLayoutData(SWTHelper.getFillGridData(3, true, 1, true));
        new Label(cBottom, SWT.NONE).setText(Messages.TerminDialog_typeandstate);
        Label lGrund = new Label(cBottom, SWT.NONE);
        lGrund.setText(Messages.TerminDialog_reason);
        lGrund.setLayoutData(SWTHelper.getFillGridData(2, false, 1, false));
        cbTyp = new Combo(cBottom, SWT.SINGLE | SWT.READ_ONLY);
        setItemTypes();
        Point pTyp = cbTyp.computeSize(SWT.DEFAULT, SWT.DEFAULT);
        tGrund = new Text(cBottom, SWT.BORDER | SWT.MULTI);
        tGrund.setLayoutData(SWTHelper.getFillGridData(2, true, 2, true));
        cbStatus = new Combo(cBottom, SWT.SINGLE | SWT.READ_ONLY);
        cbStatus.setItems(Termin.TerminStatus);
        Point pStatus = cbStatus.computeSize(SWT.DEFAULT, SWT.DEFAULT);
        int xMax = Math.max(pTyp.x, pStatus.x);
        cbTyp.setLayoutData(new GridData(xMax, SWT.DEFAULT));
        cbStatus.setLayoutData(new GridData(xMax, SWT.DEFAULT));
        StatusTypListener statusTypListener = new StatusTypListener();
        cbTyp.addSelectionListener(statusTypListener);
        cbStatus.addSelectionListener(statusTypListener);

        String val = tMap.get(Termin.TerminTypes[1]);
        if (val == null) {
            val = tMap.get(Messages.TerminDialog_32);
        }
        niDauer.setValue(Integer.parseInt(val));
        bSerie.setEnabled(false);
        // bSearch.setEnabled(false);
        // bNext.setEnabled(false);
        // bPrev.setEnabled(false);
        ret.setSize(ret.computeSize(SWT.DEFAULT, SWT.DEFAULT));
        return sc;
    }

    /**
     * mgliche Termintypen setzen (nur die, die eine Dauer!=0 haben)
     * 
     */
    private void setItemTypes() {
        cbTyp.removeAll();
        for (String t : Termin.TerminTypes) {
            String ts = tMap.get(t);
            if ((ts != null) && (ts.equals("0"))) { //$NON-NLS-1$
                continue;
            }
            cbTyp.add(t);
        }
    }

    /**
     * Status- oder Typnderungen setzen
     * 
     * @author gerry
     * 
     */
    class StatusTypListener extends SelectionAdapter {
        @Override
        public void widgetSelected(final SelectionEvent e) {
            if (e.getSource().equals(cbTyp)) {
                String type = cbTyp.getItem(cbTyp.getSelectionIndex());
                if (actPlannable instanceof Termin) {
                    ((Termin) actPlannable).setType(type);
                    bModified = true;
                } else if (actPlannable instanceof Termin.Free) {
                    Hashtable<String, String> map = Plannables.getTimePrefFor(agenda.getActResource());
                    String nt = map.get(type);
                    if (nt == null) {
                        nt = map.get("std"); //$NON-NLS-1$
                        if (nt == null) {
                            nt = "10"; //$NON-NLS-1$
                        }
                    }
                    int en = Integer.parseInt(nt);
                    niDauer.setValue(en);
                    slider.set();
                }
            } else if (e.getSource().equals(cbStatus)) {
                if (actPlannable instanceof Termin) {
                    ((Termin) actPlannable).setStatus(cbStatus.getItem(cbStatus.getSelectionIndex()));
                    bModified = true;
                }
            }
            setEnablement();
        }

    }

    @Override
    public void create() {
        setShellStyle(getShellStyle() | SWT.RESIZE);
        super.create();

        setMessage(Messages.TerminDialog_editTermins);
        setTitleImage(Images.IMG_LOGO.getImage());
        getShell().setText(Messages.TerminDialog_termin);
        dayBar.recalc();
        if (actPlannable instanceof Termin) {
            lTerminListe.add(((Termin) actPlannable).getLabel());
            lTermine.add((Termin) actPlannable);
            lTerminListe.select(0);
        }
        if (actKontakt == null) {
            setTitle(Messages.TerminDialog_noPatSelected);
            tNr.setText(""); //$NON-NLS-1$
            if (actPlannable instanceof Termin) {
                tName.setText(((Termin) actPlannable).getPersonalia());
            } else {
                tName.setText(""); //$NON-NLS-1$
            }
            tBem.setText(""); //$NON-NLS-1$
        } else {
            setTitle(actKontakt.getLabel());
            tNr.setText(Kontakt.FLD_SHORT_LABEL);
            tName.setText(actKontakt.getLabel());
            tBem.setText(actKontakt.getBemerkung());
        }

        setAll();
    }

    private void setAll() {
        tiVon.setTimeInMinutes(actPlannable.getStartMinute());
        dp.setDate(new TimeTool(actPlannable.getDay()).getTime());
        // actDate.setTime(dp.getDate());
        agenda.setActDate(new TimeTool(dp.getDate().getTime()));
        agenda.setActResource(cbMandant.getText());
        // actBereich = cbMandant.getText();

        if (actPlannable instanceof Termin.Free) {
            setCombo(cbTyp, Termin.typStandard(), 0);
            setCombo(cbStatus, Termin.statusStandard(), 0);
            bChange.setEnabled(false);
            String dauer = tMap.get(Termin.typStandard());
            if (dauer == null) {
                dauer = tMap.get(Messages.TerminDialog_40);
            }
            if (dauer == null) {
                dauer = "15"; //$NON-NLS-1$
            }
            niDauer.setValue(Integer.parseInt(dauer));
        } else {

            Termin actTermin = (Termin) actPlannable;
            tGrund.setText(actTermin.getGrund());
            setCombo(cbTyp, actTermin.getType(), 0);
            setCombo(cbStatus, actTermin.getStatus(), 0);
            bLocked.setSelection(actTermin.getFlag(Termin.SW_LOCKED));
            niDauer.getControl().setSelection(actPlannable.getDurationInMinutes());
            bEmergency.setSelection(StringUtils.equals(actTermin.get(Termin.FLD_PRIORITY), "1"));
        }
        dayBar.redraw();
        slider.set();
    }

    private void enable(final boolean mode) {
        msg = Messages.TerminDialog_editTermins;
        bChange.setEnabled(mode);
        bSave.setEnabled(mode);
        getButton(IDialogConstants.OK_ID).setEnabled(mode);
        slider.setBackground(UiDesk.getColor(UiDesk.COL_LIGHTGREY)); //$NON-NLS-1$

        if (!mode) {
            slider.setBackground(UiDesk.getColor(UiDesk.COL_DARKGREY)); //$NON-NLS-1$
            msg = Messages.TerminDialog_editTermins + "\n\t" + Messages.TerminDialog_collision;
        }

        getShell().getDisplay().asyncExec(new Runnable() {
            @Override
            public void run() {
                setMessage(msg, mode ? IMessageProvider.NONE : IMessageProvider.ERROR);
            }
        });
    }

    private void setEnablement() {
        TimeSpan ts = new TimeSpan(tiVon.setTimeTool(agenda.getActDate()), niDauer.getValue());
        if (actPlannable instanceof Termin.Free) {
            if (Plannables.collides(ts, dayBar.list, null) || terminOverlaps(agenda.getActDate(), ts)) {
                enable(false);
            } else {
                enable(true);
            }
            // bLocked.setEnabled(false);
        } else {
            if (Plannables.collides(ts, dayBar.list, (Termin) actPlannable)) {
                enable(false);
            } else {
                if (bModified) {
                    if (actKontakt != null && terminOverlaps(agenda.getActDate(), ts)) {
                        enable(false);
                        return;
                    }
                    enable(true);
                } else {
                    enable(false);
                }
            }
            // bLocked.setEnabled(true);
        }

    }

    private void setCombo(final Combo combo, final String value, final int def) {
        String[] elems = combo.getItems();
        int idx = StringTool.getIndex(elems, value);
        if (idx == -1) {
            idx = def;
        }
        combo.select(idx);
    }

    /**
     * Klasse fr die bersichtliche Darstellung eines Tages-Balkens
     * 
     * @author Gerry
     * 
     */
    class DayOverview extends Composite implements PaintListener {

        Point d;
        int sep;

        java.util.List<IPlannable> list;

        DayOverview(final Composite parent) {
            super(parent, SWT.NONE);
            addPaintListener(this);
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseDown(final MouseEvent e) {
                    if (e.y > sep + 2) {
                        rasterIndex = (rasterIndex >= rasterValues.length) ? 0 : rasterIndex + 1;
                        CoreHub.userCfg.set("agenda/dayView/raster", rasterIndex); //$NON-NLS-1$
                        redraw();
                    } else {
                        // super.mouseDown(e);
                        Point loc = slider.getLocation();
                        slider.setLocation(e.x, loc.y);
                        slider.updateTimes();
                    }
                }

            });
        }

        /**
         * Tagesbalken neu kalkulieren (Startzeit, Endzeit, pixel pro Minute etc.)
         * 
         */
        void recalc() {
            list = Plannables.loadTermine(agenda.getActResource(), agenda.getActDate());

            tagStart = ts * 60;
            tagEnd = te * 60;
            int i = 0;
            IPlannable pi = list.get(i);
            // Tagesanzeige ca. eine halbe Stunde vor dem ersten reservierten
            // Zeitraum anfangen
            if (pi.getType().equals(Termin.typReserviert())) {
                tagStart = pi.getDurationInMinutes() < 31 ? 0 : pi.getDurationInMinutes() - 30;
            } else {
                tagStart = 0;
            }
            i = list.size() - 1;
            pi = list.get(i);
            int end = pi.getStartMinute() + pi.getDurationInMinutes();
            if (end < 1408) {
                tagEnd = 1439;
            }
            if (tagStart != 0) {
                tagStart = tagStart / 60 * 60;
            }
            if (tagEnd < 1439) {
                tagEnd = (tagEnd + 30) / 60 * 60;
            }
            minutes = tagEnd - tagStart;
            d = this.getSize();
            pixelPerMinute = d.x / minutes;
            sep = d.y / 2;
            /*
             * double minutes=(tagEnd-tagStart); minutewidth=d.x/minutes;
             */
        }

        @Override
        public Point computeSize(final int wHint, final int hHint, final boolean changed) {
            return new Point(getParent().getSize().x, 40);
        }

        /**
         * Tagesbalken zeichnen
         */
        public void paintControl(final PaintEvent pe) {
            recalc();
            GC g = pe.gc;
            Color def = g.getBackground();
            // Balken zeichnen
            g.setBackground(UiDesk.getColor(UiDesk.COL_GREEN));
            Rectangle r = new Rectangle(0, 0, d.x, sep - 2);
            g.fillRectangle(r);

            // Termine darauf zeichnen
            for (IPlannable p : list) {
                Plannables.paint(g, p, r, tagStart, tagEnd);
            }

            // Lineal zeichnen
            g.setBackground(def);
            g.setFont(UiDesk.getFont(Preferences.USR_SMALLFONT));

            g.drawLine(0, sep, d.x, sep);
            if (rasterIndex >= rasterValues.length) {
                rasterIndex = 0;
                CoreHub.userCfg.set("agenda/dayView/raster", rasterIndex); //$NON-NLS-1$
            }
            double chunkwidth = rasterValues[rasterIndex] * pixelPerMinute;
            int chunksPerHour = 60 / rasterValues[rasterIndex];
            int ch = chunksPerHour - 1;
            int hr = tagStart / 60;
            if (chunkwidth < 0.1) {
                return;
            }
            for (double x = 0; x <= d.x; x += chunkwidth) {
                int lx = (int) Math.round(x);
                if (++ch == chunksPerHour) {
                    g.drawLine(lx, sep - 1, lx, sep + 6);
                    g.drawString(Integer.toString(hr++), lx, sep + 6);
                    ch = 0;
                } else {
                    g.drawLine(lx, sep, lx, sep + 4);
                }
            }

            slider.redraw();
        }
    }

    private class Slider extends Composite implements MouseListener, MouseMoveListener {
        boolean isDragging;

        Slider(final Composite parent) {
            super(parent, SWT.BORDER);
            setBackground(UiDesk.getColor(UiDesk.COL_RED)); //$NON-NLS-1$
            addMouseListener(this);
            addMouseMoveListener(this);
        }

        void set() {
            int v = tiVon.getTimeAsMinutes();
            int d = niDauer.getValue();
            Rectangle r = getParent().getBounds();
            int x = (int) Math.round((v - tagStart) * pixelPerMinute);
            int w = (int) Math.round(d * pixelPerMinute);
            setBounds(x, 0, w, r.height / 2);
            tiBis.setTimeInMinutes(v + d);
            bModified = true;
            setEnablement();
        }

        public void mouseDoubleClick(final MouseEvent e) {
        }

        public void mouseDown(final MouseEvent e) {
            isDragging = true;
        }

        public void mouseUp(final MouseEvent e) {
            if (isDragging) {
                isDragging = false;
                updateTimes();
            }
        }

        public void mouseMove(final MouseEvent e) {
            if (isDragging) {
                Point loc = getLocation();
                int x = loc.x + e.x;
                setLocation(x, loc.y);
            }

        }

        public void updateTimes() {
            Point loc = getLocation();
            Rectangle rec = getParent().getBounds();
            double minutes = tagEnd - tagStart;
            double minutesPerPixel = minutes / rec.width;
            int minute = (int) Math.round(loc.x * minutesPerPixel) + tagStart;
            int raster = rasterValues[rasterIndex];
            minute = ((minute + (raster >> 1)) / raster) * raster;
            tiVon.setTimeInMinutes(minute);
            set();
        }

    }

    public void setTime(TimeTool time) {
        tiVon.setText(time.toString(TimeTool.TIME_SMALL));
        slider.set();
    }

    @Override
    protected void okPressed() {
        createTermin(false);
        super.okPressed();
    }

    private void createTermin(final boolean bMulti) {
        int von = tiVon.getTimeAsMinutes();
        int bis = von + niDauer.getValue();
        String typ = cbTyp.getItem(cbTyp.getSelectionIndex());
        String status = cbStatus.getItem(cbStatus.getSelectionIndex());
        String priority = bEmergency.getSelection() ? "1" : "0";
        Termin actTermin = null;
        if (actPlannable instanceof Termin.Free) {
            Termin newTermin = new Termin(agenda.getActResource(),
                    agenda.getActDate().toString(TimeTool.DATE_COMPACT), von, bis, typ, status, priority);
            actTermin = newTermin;
        } else {
            actTermin = (Termin) actPlannable;
            if (bMulti) {
                Termin clonedTermin = (Termin) actTermin.clone();
                AcquireLockBlockingUi.aquireAndRun(clonedTermin, new ILockHandler() {
                    @Override
                    public void lockFailed() {
                        clonedTermin.delete();
                    }

                    @Override
                    public void lockAcquired() {
                        // do nothing

                    }
                });
            }

            actTermin.set(new String[] { "BeiWem", "Tag", "Beginn", "Dauer", "Typ", "Status", Termin.FLD_PRIORITY },
                    new String[] { agenda.getActResource(), agenda.getActDate().toString(TimeTool.DATE_COMPACT),
                            Integer.toString(von), Integer.toString(bis - von), typ, status, priority });
        }
        lTerminListe.add(actTermin.getLabel());
        lTermine.add(actTermin);
        final Termin lockTermin = actTermin;
        AcquireLockBlockingUi.aquireAndRun(lockTermin, new ILockHandler() {

            @Override
            public void lockFailed() {
                // do nothing
            }

            @Override
            public void lockAcquired() {
                if (actKontakt != null) {
                    lockTermin.setKontakt(actKontakt);
                } else {
                    lockTermin.set("Wer", tName.getText()); //$NON-NLS-1$
                }
                lockTermin.setGrund(tGrund.getText());
                lockTermin.set(Termin.FLD_CREATOR, ElexisEventDispatcher.getSelected(User.class).getLabel());

                if (bLocked.getSelection()) {
                    lockTermin.setFlag(Termin.SW_LOCKED);
                }
                ElexisEventDispatcher.reload(Termin.class);
            }
        });
        dayBar.recalc();
        actPlannable = actTermin;
        setEnablement();
    }

    /**
     * checks if the given appointment overlaps with any other appointment of this patient
     * 
     * @param actDate
     *            date of the appointment
     * @param terminTS
     *            timespan of the appointment
     * @return true if there is a collision
     */
    private boolean terminOverlaps(TimeTool actDate, TimeSpan terminTS) {
        boolean avoidPatientDoubleBooking = CoreHub.localCfg.get(
                PreferenceConstants.AG_AVOID_PATIENT_DOUBLE_BOOKING,
                PreferenceConstants.AG_AVOID_PATIENT_DOUBLE_BOOKING_DEFAULT);

        if (avoidPatientDoubleBooking && actKontakt != null) {
            Query<Termin> tQuery = new Query<Termin>(Termin.class);
            tQuery.add(Termin.FLD_PATIENT, Query.EQUALS, actKontakt.getId());
            tQuery.add(Termin.FLD_TAG, Query.EQUALS, actDate.toString(TimeTool.DATE_COMPACT));
            java.util.List<Termin> termine = tQuery.execute();

            if (actPlannable instanceof Termin.Free) {
                for (Termin t : termine) {
                    TimeSpan ts = t.getTimeSpan();
                    if (ts.overlap(terminTS) != null) {
                        return true;
                    }
                }
            } else {
                Termin curTermin = (Termin) actPlannable;
                for (Termin t : termine) {
                    // only compare if it's not the currently open appointment
                    if (!t.getId().equals(curTermin.getId())) {
                        TimeSpan ts = t.getTimeSpan();
                        if (ts.overlap(terminTS) != null) {
                            return true;
                        }
                    }
                }
            }
            return false;
        }
        return false;
    }
}