/*******************************************************************************
* Copyright (c) 2007-2011, 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
*
*******************************************************************************/
package ch.elexis.agenda.views;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
import ch.elexis.actions.Activator;
import ch.elexis.actions.AgendaActions;
import ch.elexis.actions.IBereichSelectionEvent;
import ch.elexis.agenda.BereichSelectionHandler;
import ch.elexis.agenda.Messages;
import ch.elexis.agenda.acl.ACLContributor;
import ch.elexis.agenda.data.ICalTransfer;
import ch.elexis.agenda.data.IPlannable;
import ch.elexis.agenda.data.Termin;
import ch.elexis.agenda.data.TerminUtil;
import ch.elexis.agenda.preferences.PreferenceConstants;
import ch.elexis.agenda.series.SerienTermin;
import ch.elexis.agenda.series.ui.SerienTerminDialog;
import ch.elexis.agenda.ui.BereichMenuCreator;
import ch.elexis.agenda.util.Plannables;
import ch.elexis.core.constants.Preferences;
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.data.events.Heartbeat.HeartListener;
import ch.elexis.core.ui.UiDesk;
import ch.elexis.core.ui.actions.GlobalEventDispatcher;
import ch.elexis.core.ui.actions.IActivationListener;
import ch.elexis.core.ui.actions.RestrictedAction;
import ch.elexis.core.ui.dialogs.KontaktSelektor;
import ch.elexis.core.ui.events.ElexisUiEventListenerImpl;
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.locks.LockRequestingRestrictedAction;
import ch.elexis.core.ui.util.SWTHelper;
import ch.elexis.data.Anwender;
import ch.elexis.data.Kontakt;
import ch.elexis.data.Patient;
import ch.elexis.data.PersistentObject;
import ch.elexis.data.Query;
import ch.elexis.dialogs.TagesgrenzenDialog;
import ch.elexis.dialogs.TerminDialog;
import ch.elexis.dialogs.TerminListeDruckenDialog;
import ch.elexis.dialogs.TermineDruckenDialog;
import ch.rgw.tools.Log;
import ch.rgw.tools.TimeTool;
public abstract class BaseAgendaView extends ViewPart implements HeartListener,
IActivationListener, IBereichSelectionEvent {
// protected Synchronizer pinger;
protected SelectionListener sListen = new SelectionListener();
TableViewer tv;
BaseAgendaView self;
protected LockRequestingRestrictedAction<Termin> terminAendernAction, terminKuerzenAction, terminVerlaengernAction;
protected RestrictedAction newTerminAction;
protected IAction blockAction;
protected IAction dayLimitsAction, newViewAction, printAction, exportAction, importAction,
newTerminForAction;
protected IAction printPatientAction;
private BereichMenuCreator bmc = new BereichMenuCreator();
MenuManager menu = new MenuManager();
protected Log log = Log.get("Agenda"); //$NON-NLS-1$
Activator agenda = Activator.getDefault();
private final ElexisEventListener eeli_termin = new ElexisUiEventListenerImpl(Termin.class,
ElexisEvent.EVENT_RELOAD) {
public void runInUi(ElexisEvent ev){
if (!tv.getControl().isDisposed()) {
tv.refresh(true);
}
}
};
private final ElexisEventListener eeli_user = new ElexisUiEventListenerImpl(Anwender.class,
ElexisEvent.EVENT_USER_CHANGED) {
public void runInUi(ElexisEvent ev){
updateActions();
if (tv != null) {
if (!tv.getControl().isDisposed()) {
tv.getControl().setFont(UiDesk.getFont(Preferences.USR_DEFAULTFONT));
}
}
setBereich(CoreHub.userCfg.get(PreferenceConstants.AG_BEREICH, agenda.getActResource()));
}
};
private IMenuManager mgr;
private IAction bereichMenu;
protected BaseAgendaView(){
self = this;
BereichSelectionHandler.addBereichSelectionListener(this);
}
abstract public void create(Composite parent);
@Override
public void createPartControl(Composite parent){
setBereich(agenda.getActResource());
create(parent);
makeActions();
tv.setContentProvider(new AgendaContentProvider());
tv.setUseHashlookup(true);
tv.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event){
IPlannable pl = getSelection();
if (pl == null) {
newTerminAction.run();
} else {
if (pl.isRecurringDate()) {
// TODO Locking
SerienTermin st = new SerienTermin(pl);
new SerienTerminDialog(UiDesk.getTopShell(), st).open();
tv.refresh(true);
} else {
terminAendernAction.run();
tv.refresh(true);
}
}
}
});
menu.setRemoveAllWhenShown(true);
menu.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager manager){
if (ElexisEventDispatcher.getSelected(Termin.class) == null) {
manager.add(newTerminAction);
manager.add(blockAction);
} else {
manager.add(AgendaActions.getTerminStatusAction());
manager.add(terminKuerzenAction);
manager.add(terminVerlaengernAction);
manager.add(terminAendernAction);
manager.add(AgendaActions.getDelTerminAction());
}
updateActions();
}
});
Menu cMenu = menu.createContextMenu(tv.getControl());
tv.getControl().setMenu(cMenu);
// GlobalEvents.getInstance().addBackingStoreListener(this);
GlobalEventDispatcher.addActivationListener(this, getViewSite().getPart());
tv.setInput(getViewSite());
// pinger=new ch.elexis.actions.Synchronizer();
updateActions();
}
public IPlannable getSelection(){
IStructuredSelection sel = (IStructuredSelection) tv.getSelection();
if ((sel == null || (sel.isEmpty()))) {
return null;
} else {
IPlannable pl = (IPlannable) sel.getFirstElement();
return pl;
}
}
@Override
public void dispose(){
GlobalEventDispatcher.removeActivationListener(this, getViewSite().getPart());
super.dispose();
}
@Override
public void setFocus(){}
public void heartbeat(){
log.log("Heartbeat", Log.DEBUGMSG); //$NON-NLS-1$
eeli_termin.catchElexisEvent(new ElexisEvent(null, Termin.class, ElexisEvent.EVENT_RELOAD));
// GlobalEvents.getInstance().fireUpdateEvent(Termin.class);
// pinger.doSync();
}
public void activation(boolean mode){/* leer */
}
public void visible(boolean mode){
if (mode == true) {
CoreHub.heart.addListener(this);
tv.addSelectionChangedListener(sListen);
ElexisEventDispatcher.getInstance().addListeners(eeli_termin, eeli_user);
heartbeat();
updateActions();
} else {
CoreHub.heart.removeListener(this);
tv.removeSelectionChangedListener(sListen);
ElexisEventDispatcher.getInstance().removeListeners(eeli_termin, eeli_user);
}
};
public void setBereich(String b){
agenda.setActResource(b);
}
public abstract void setTermin(Termin t);
class AgendaContentProvider implements IStructuredContentProvider {
public Object[] getElements(Object inputElement){
if (CoreHub.acl.request(ACLContributor.DISPLAY_APPOINTMENTS)) {
String resource = agenda.getActResource();
TimeTool date = agenda.getActDate();
TerminUtil.updateBoundaries(resource, date);
return Plannables.loadDay(resource, date);
} else {
return new Object[0];
}
}
public void dispose(){ /* leer */
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput){/* leer */
}
};
class SelectionListener implements ISelectionChangedListener {
StructuredViewer sv;
public void selectionChanged(SelectionChangedEvent event){
IStructuredSelection sel = (IStructuredSelection) event.getSelection();
if ((sel == null) || sel.isEmpty()) {
ElexisEventDispatcher.clearSelection(Termin.class);
} else {
Object o = sel.getFirstElement();
if (o instanceof Termin) {
setTermin((Termin) o);
} else if (o instanceof Termin.Free) {
ElexisEventDispatcher.clearSelection(Termin.class);
}
}
}
}
protected void updateActions(){
dayLimitsAction.setEnabled(CoreHub.acl.request(ACLContributor.CHANGE_DAYSETTINGS));
newTerminAction.reflectRight();
terminKuerzenAction.reflectRight();
terminVerlaengernAction.reflectRight();
terminAendernAction.reflectRight();
AgendaActions.updateActions();
}
protected void makeActions(){
dayLimitsAction = new Action(Messages.BaseAgendaView_dayLimits) {
@Override
public void run(){
new TagesgrenzenDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow()
.getShell(), agenda.getActDate().toString(TimeTool.DATE_COMPACT),
agenda.getActResource()).open();
tv.refresh(true);
}
};
dayLimitsAction.setId("ch.elexis.agenda.actions.dayLimitsAction");
blockAction = new Action(Messages.TagesView_lockPeriod) {
@Override
public void run(){
IStructuredSelection sel = (IStructuredSelection) tv.getSelection();
if (sel != null && !sel.isEmpty()) {
IPlannable p = (IPlannable) sel.getFirstElement();
if (p instanceof Termin.Free) {
new Termin(agenda.getActResource(), agenda.getActDate().toString(
TimeTool.DATE_COMPACT), p.getStartMinute(), p.getDurationInMinutes()
+ p.getStartMinute(), Termin.typReserviert(), Termin.statusLeer());
ElexisEventDispatcher.reload(Termin.class);
}
}
}
};
terminAendernAction = new LockRequestingRestrictedAction<Termin>(ACLContributor.CHANGE_APPOINTMENTS,
Messages.TagesView_changeTermin) {
{
setImageDescriptor(Images.IMG_EDIT.getImageDescriptor());
setToolTipText(Messages.TagesView_changeThisTermin);
}
@Override
public Termin getTargetedObject() {
return (Termin) ElexisEventDispatcher.getSelected(Termin.class);
}
@Override
public void doRun(Termin element) {
AcquireLockBlockingUi.aquireAndRun(element, new ILockHandler() {
@Override
public void lockFailed(){
// do nothing
}
@Override
public void lockAcquired(){
TerminDialog dlg = new TerminDialog(element);
dlg.open();
}
});
if (tv != null) {
tv.refresh(true);
}
}
};
terminKuerzenAction = new LockRequestingRestrictedAction<Termin>(ACLContributor.CHANGE_APPOINTMENTS,
Messages.TagesView_shortenTermin) {
@Override
public Termin getTargetedObject() {
return (Termin) ElexisEventDispatcher.getSelected(Termin.class);
}
@Override
public void doRun(Termin element) {
element.setDurationInMinutes(element.getDurationInMinutes() >> 1);
ElexisEventDispatcher.reload(Termin.class);
}
};
terminVerlaengernAction = new LockRequestingRestrictedAction<Termin>(ACLContributor.CHANGE_APPOINTMENTS,
Messages.TagesView_enlargeTermin) {
@Override
public Termin getTargetedObject() {
return (Termin) ElexisEventDispatcher.getSelected(Termin.class);
}
@Override
public void doRun(Termin t) {
agenda.setActDate(t.getDay());
Termin n = Plannables.getFollowingTermin(agenda.getActResource(), agenda.getActDate(), t);
if (n != null) {
t.setEndTime(n.getStartTime());
// t.setDurationInMinutes(t.getDurationInMinutes()+15);
ElexisEventDispatcher.reload(Termin.class);
}
}
};
newTerminAction = new RestrictedAction(ACLContributor.CHANGE_DAYSETTINGS, Messages.TagesView_newTermin) {
{
setImageDescriptor(Images.IMG_NEW.getImageDescriptor());
setToolTipText(Messages.TagesView_createNewTermin);
}
@Override
public void doRun() {
TerminDialog dlg = new TerminDialog(null);
dlg.open();
if (tv != null) {
tv.refresh(true);
}
}
};
newTerminForAction = new Action("Neuer Termin für...") {
{
setImageDescriptor(Images.IMG_NEW.getImageDescriptor());
setToolTipText("Dialog zum Auswählen eines Kontakts für den Termin öffnen");
}
@Override
public void run(){
KontaktSelektor ksl =
new KontaktSelektor(getSite().getShell(), Kontakt.class, "Terminvergabe",
"Bitte wählen Sie aus, wer einen Termin braucht", Kontakt.DEFAULT_SORT);
IPlannable sel = getSelection();
TerminDialog dlg = new TerminDialog(null);
dlg.open();
if (tv != null) {
tv.refresh(true);
}
}
};
printAction = new Action(Messages.BaseAgendaView_printDayList) {
{
setImageDescriptor(Images.IMG_PRINTER.getImageDescriptor());
setToolTipText(Messages.BaseAgendaView_printListOfDay);
}
@Override
public void run(){
IPlannable[] liste =
Plannables.loadDay(agenda.getActResource(), agenda.getActDate());
TerminListeDruckenDialog dlg =
new TerminListeDruckenDialog(getViewSite().getShell(), liste);
dlg.open();
if (tv != null) {
tv.refresh(true);
}
}
};
printPatientAction = new Action(Messages.BaseAgendaView_printPatAppointments) {
{
setImageDescriptor(Images.IMG_PRINTER.getImageDescriptor());
setToolTipText(Messages.BaseAgendaView_printFutureAppsOfSelectedPatient);
}
@Override
public void run(){
Patient patient = ElexisEventDispatcher.getSelectedPatient();
if (patient != null) {
Query<Termin> qbe = new Query<Termin>(Termin.class);
qbe.add(Termin.FLD_PATIENT, Query.EQUALS, patient.getId());
qbe.add(PersistentObject.FLD_DELETED, Query.NOT_EQUAL, StringConstants.ONE);
qbe.add(Termin.FLD_TAG, Query.GREATER_OR_EQUAL,
new TimeTool().toString(TimeTool.DATE_COMPACT));
qbe.orderBy(false, Termin.FLD_TAG, Termin.FLD_BEGINN);
java.util.List<Termin> list = qbe.execute();
if (list != null) {
boolean directPrint =
CoreHub.localCfg.get(
PreferenceConstants.AG_PRINT_APPOINTMENTCARD_DIRECTPRINT,
PreferenceConstants.AG_PRINT_APPOINTMENTCARD_DIRECTPRINT_DEFAULT);
TermineDruckenDialog dlg =
new TermineDruckenDialog(getViewSite().getShell(),
list.toArray(new Termin[0]));
if (directPrint) {
dlg.setBlockOnOpen(false);
dlg.open();
if (dlg.doPrint()) {
dlg.close();
} else {
SWTHelper.alert(Messages.BaseAgendaView_errorWhileprinting,
Messages.BaseAgendaView_errorHappendPrinting);
}
} else {
dlg.setBlockOnOpen(true);
dlg.open();
}
}
}
}
};
exportAction = new Action(Messages.BaseAgendaView_exportAgenda) {
{
setToolTipText(Messages.BaseAgendaView_exportAppointsments);
setImageDescriptor(Images.IMG_GOFURTHER.getImageDescriptor());
}
@Override
public void run(){
ICalTransfer ict = new ICalTransfer();
ict.doExport(agenda.getActDate(), agenda.getActDate(), agenda.getActResource());
}
};
importAction = new Action(Messages.BaseAgendaView_importAgenda) {
{
setToolTipText(Messages.BaseAgendaView_importFromIcal);
setImageDescriptor(Images.IMG_IMPORT.getImageDescriptor());
}
@Override
public void run(){
ICalTransfer ict = new ICalTransfer();
ict.doImport(agenda.getActResource());
}
};
bereichMenu = new Action(Messages.TagesView_bereich, Action.AS_DROP_DOWN_MENU) {
Menu mine;
{
setToolTipText(Messages.TagesView_selectBereich);
setMenuCreator(bmc);
}
};
mgr = getViewSite().getActionBars().getMenuManager();
mgr.add(bereichMenu);
mgr.add(dayLimitsAction);
mgr.add(newViewAction);
mgr.add(exportAction);
mgr.add(importAction);
mgr.add(printAction);
mgr.add(printPatientAction);
}
@Override
public void bereichSelectionEvent(String bereich){
setPartName("Agenda " + bereich);
ElexisEventDispatcher.reload(Termin.class);
eeli_termin.catchElexisEvent(new ElexisEvent(null, Termin.class, ElexisEvent.EVENT_RELOAD));
}
}