/*******************************************************************************
* Copyright (c) 2015, Daniel Ludin
* 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:
* Daniel Ludin (ludin@hispeed.ch) - initial implementation
*******************************************************************************/
package ch.gpb.elexis.cst.view.profileeditor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import ch.elexis.core.data.activator.CoreHub;
import ch.elexis.core.data.events.Heartbeat.HeartListener;
import ch.elexis.core.ui.UiDesk;
import ch.gpb.elexis.cst.Activator;
import ch.gpb.elexis.cst.data.CstProfile;
import ch.gpb.elexis.cst.data.CstStateItem;
import ch.gpb.elexis.cst.data.CstStateItem.StateType;
import ch.gpb.elexis.cst.dialog.CstReminderDialog;
import ch.gpb.elexis.cst.preferences.Messages;
import ch.gpb.elexis.cst.service.CstService;
public class RemindersComposite extends CstComposite implements HeartListener/* IActivationListener */{
CstProfile aProfile;
TreeViewer treeviewer;
Action actionAddObject;
Action actionDeleteObject;
Action actionEditObject;
Image imgExclam = UiDesk.getImage(Activator.IMG_EXCLAM_NAME);
List<Image> imageList = new ArrayList<Image>();
Label lblHeart;
Label lblCheckingForActions;
public RemindersComposite(Composite parent) {
super(parent, SWT.NONE);
GridLayout gridLayout = new GridLayout(4, false);
setLayout(gridLayout);
createLayout(this);
treeviewer = new TreeViewer(this, SWT.BORDER);
Tree tree_1 = treeviewer.getTree();
GridData gd_tree_1 = new GridData(SWT.LEFT, SWT.CENTER, false, false, 4, 1);
gd_tree_1.heightHint = 230;
gd_tree_1.widthHint = 500;
tree_1.setLayoutData(gd_tree_1);
treeviewer.setContentProvider(new ViewContentProvider());
treeviewer.setLabelProvider(new ViewLabelProvider());
Button btnNewAction = new Button(this, SWT.NONE);
btnNewAction.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1));
btnNewAction.setText("Start new event chain");
btnNewAction.addSelectionListener(new NewItemListener());
Button btnExpandAll = new Button(this, SWT.NONE);
btnExpandAll.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1));
btnExpandAll.setText("Expand All");
btnExpandAll.addSelectionListener(new ExpandAllListener());
MenuManager menuMgr = new MenuManager();
Menu menu = menuMgr.createContextMenu(treeviewer.getControl());
menuMgr.addMenuListener(new IMenuListener() {
@Override
public void menuAboutToShow(IMenuManager manager) {
if (treeviewer.getSelection().isEmpty()) {
return;
}
if (treeviewer.getSelection() instanceof IStructuredSelection) {
IStructuredSelection selection = (IStructuredSelection) treeviewer.getSelection();
manager.add(actionAddObject);
manager.add(actionDeleteObject);
manager.add(actionEditObject);
}
}
});
menuMgr.setRemoveAllWhenShown(true);
treeviewer.getControl().setMenu(menu);
treeviewer.getTree().setHeaderVisible(true);
ColumnViewerToolTipSupport.enableFor(treeviewer);
makeActions();
CoreHub.heart.addListener(this);
new Label(this, SWT.NONE);
lblHeart = new Label(this, SWT.NONE);
lblHeart.setText(Messages.RemindersComposite_lblHeart_text);
GridData gd_lblHeart = new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1);
gd_lblHeart.heightHint = 50;
gd_lblHeart.widthHint = 50;
lblHeart.setLayoutData(gd_lblHeart);
new Label(this, SWT.NONE);
new Label(this, SWT.NONE);
new Label(this, SWT.NONE);
lblCheckingForActions = new Label(this, SWT.NONE);
lblCheckingForActions.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1));
lblCheckingForActions.setText(Messages.RemindersComposite_lblCheckingForActions_text);
treeviewer.addDoubleClickListener(new IDoubleClickListener() {
@Override
public void doubleClick(DoubleClickEvent event) {
TreeViewer viewer = (TreeViewer) event.getViewer();
IStructuredSelection thisSelection = (IStructuredSelection) event.getSelection();
Object selectedNode = thisSelection.getFirstElement();
viewer.setExpandedState(selectedNode,
!viewer.getExpandedState(selectedNode));
}
});
imageList = Arrays.asList(imgHeart1, imgHeart2, imgHeart3, imgHeartA, imgHeartB, imgHeartC, imgHeartD,
imgHeartE);
lblCheckingForActions.setVisible(false);
lblHeart.setVisible(false);
}
// dynamic Layout elements
private void createLayout(Composite parent) {
Label labelTherapievorschlag = new Label(parent, SWT.NONE);
labelTherapievorschlag.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 4, 1));
labelTherapievorschlag.setText(Messages.RemindersComposite_title_reminder);
labelTherapievorschlag.setSize(200, 20);
}
@Override
public void dispose() {
super.dispose();
}
/**
* checking for actions coming due
* Adding the Hearbeat Listener is done by activation of CstProfileEditor,
* even when there is no profile selected yet. thus the return statement.
*/
@Override
public void heartbeat() {
//System.out.println("HEARTBEAT");
if (aProfile == null) {
return;
}
new HeartbeatThread().start();
//UiDesk.asyncExec(new HeartbeatThread());
}
class NewItemListener extends SelectionAdapter {
@Override
public void widgetSelected(final SelectionEvent e) {
addObject(null);
treeviewer.setInput(CstStateItem.getRootItems(aProfile));
}
}
class ExpandAllListener extends SelectionAdapter {
@Override
public void widgetSelected(final SelectionEvent e) {
expandAll();
}
}
private void showMessage(String title, String msg) {
MessageDialog.openInformation(UiDesk.getTopShell(), title, msg);
}
public void addObject(CstStateItem selItem) {
if (aProfile == null) {
showMessage("No Profile", "Bitte w�hlen Sie ein Profil");
return;
}
CstReminderDialog dialog = new CstReminderDialog(getShell(), CoreHub.actMandant);
StateType selType = null;
String name = null;
dialog.create();
if (dialog.open() == Window.OK) {
selType = dialog.getItemType();
name = dialog.getGroupName();
} else {
return;
}
if (selItem != null) {
CstStateItem item = new CstStateItem(CstService.getCompactFromDate(new Date()), name, selType,
aProfile.getId(), selItem.getId(),
CoreHub.actMandant.getId());
System.out.println("created CstStateItem with parent: " + item.getId());
} else {
CstStateItem item = new CstStateItem(CstService.getCompactFromDate(new Date()), name, selType,
aProfile.getId(), null,
CoreHub.actMandant.getId());
System.out.println("created CstStateItem without parent: " + item.getId());
}
}
private void makeActions() {
actionAddObject = new Action() {
public void run() {
IStructuredSelection selection = (IStructuredSelection) treeviewer.getSelection();
System.out.println("sel tree: " + selection.toString());
CstStateItem selItem = (CstStateItem) selection.getFirstElement();
addObject(selItem);
treeviewer.refresh();
//expandAll();
treeviewer.setExpandedState(selItem, true);
}
};
actionAddObject.setText("Add Item");
actionAddObject.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages()
.getImageDescriptor(ISharedImages.IMG_OBJ_ADD));
actionEditObject = new Action() {
public void run() {
IStructuredSelection selection = (IStructuredSelection) treeviewer.getSelection();
System.out.println("sel tree: " + selection.toString());
CstStateItem selItem = (CstStateItem) selection.getFirstElement();
CstReminderDialog dialog = new CstReminderDialog(getShell(), CoreHub.actMandant);
dialog.create();
dialog.setName(selItem.getName());
dialog.setDescription(selItem.getDescription());
dialog.setType(selItem.getItemType());
dialog.setDate(CstService.getDateFromCompact(selItem.getDate()));
StateType selType = null;
String name = null;
String desc = null;
Date date = null;
if (dialog.open() == Window.OK) {
selType = dialog.getItemType();
name = dialog.getGroupName();
desc = dialog.getGroupDescription();
date = dialog.getDate();
} else {
return;
}
selItem.setName(name);
selItem.setDescription(desc);
selItem.setItemType(selType);
selItem.setDate(CstService.getCompactFromDate(date));
treeviewer.refresh();
//expandAll();
}
};
actionEditObject.setText("Edit Item");
actionEditObject.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages()
.getImageDescriptor(ISharedImages.IMG_ETOOL_SAVE_EDIT));
actionDeleteObject = new Action() {
public void run() {
TreeSelection selection = (TreeSelection) treeviewer.getSelection();
System.out.println("sel tree: " + selection.toString());
CstStateItem selItem = (CstStateItem) selection.getFirstElement();
//selection.getPaths();
//CstStateItem parent = (CstStateItem) selItem.getParent();
//TreeItem treeItem = (TreeItem) selection.getFirstElement();
List<CstStateItem> result = new ArrayList<CstStateItem>();
List<CstStateItem> itemsToDelete = getChildrenToDelete(selItem, result);
itemsToDelete.add(selItem);
for (CstStateItem cstStateItem : itemsToDelete) {
cstStateItem.delete();
}
treeviewer.setInput(CstStateItem.getRootItems(aProfile));
expandAll();
//
//treeviewer.setExpandedState(CstStateItem.getParent(selItem), true);
}
};
actionDeleteObject.setText("Delete Item");
actionDeleteObject.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages()
.getImageDescriptor(ISharedImages.IMG_ETOOL_DELETE));
}
private static List<CstStateItem> getChildrenToDelete(CstStateItem parent, List<CstStateItem> result) {
List<CstStateItem> items = CstStateItem.getChildren(parent);
for (CstStateItem item : items) {
result.add(item);
if (!CstStateItem.getChildren(item).isEmpty()) {
RemindersComposite.getChildrenToDelete(item, result);
}
}
return result;
}
private void expandAll() {
treeviewer.expandAll();
}
class ViewLabelProvider extends StyledCellLabelProvider {
@Override
public void update(ViewerCell cell) {
CstStateItem element = (CstStateItem) cell.getElement();
StyledString text = new StyledString();
text.append(element.getItemType().name() + ": " + element.getName());
cell.setText(text.toString());
cell.setStyleRanges(text.getStyleRanges());
// A, D, R, T
switch (element.getItemType().ordinal()) {
case 0:
cell.setForeground(ORANGE);
cell.setImage(imgAction);
break;
case 1:
cell.setForeground(COLOR_RED);
cell.setImage(imgDecision);
break;
case 2:
cell.setText(element.getItemType().name() + "" + " f�llig am:"
+ CstService.getGermanFromCompact(element.getDate()));
if (new Date().after(CstService.getDateFromCompact(element.getDate()))) {
cell.setImage(imgReminder);
cell.setBackground(COLOR_RED);
/*
cell.setText(text.toString() + " (f�llig am: "
+ CstService.getGermanFromCompact(element.getDate())
+ ") ");
*/
} else {
cell.setBackground(WHITE);
cell.setImage(imgReminder);
}
cell.setForeground(VIOLET);
break;
case 3:
cell.setForeground(GREEN);
cell.setImage(imgTrigger);
break;
default:
break;
}
super.update(cell);
}
@Override
public String getToolTipText(Object element) {
CstStateItem item = (CstStateItem) element;
return "ID: " + item.getId() + " (" + CstService.getGermanFromCompact(item.getDate()) + ")";
}
@Override
public Point getToolTipShift(Object object) {
return new Point(5, 5);
}
@Override
public int getToolTipTimeDisplayed(Object object) {
return 2000;
}
@Override
public int getToolTipDisplayDelayTime(Object object) {
return 200;
}
}
class ViewContentProvider implements ITreeContentProvider {
public void inputChanged(Viewer v, Object oldInput, Object newInput) {
}
@Override
public void dispose() {
}
@Override
public Object[] getElements(Object inputElement) {
LinkedList<CstStateItem> list = (LinkedList<CstStateItem>) inputElement;
return list.toArray();
}
@Override
public Object[] getChildren(Object parentElement) {
CstStateItem file = (CstStateItem) parentElement;
List<CstStateItem> children = CstStateItem.getChildren(file);
return children.toArray();
}
@Override
public Object getParent(Object element) {
System.out.println("getParent class: " + element.getClass());
if (element instanceof LinkedList) {
LinkedList<CstStateItem> list = (LinkedList<CstStateItem>) element;
Iterator<CstStateItem> it = list.iterator();
if (it.hasNext()) {
CstStateItem child2 = it.next();
return child2;
} else {
return null;
}
}
CstStateItem child = (CstStateItem) element;
return CstStateItem.getParent(child);
}
@Override
public boolean hasChildren(Object element) {
CstStateItem child = (CstStateItem) element;
List<CstStateItem> children = CstStateItem.getChildren(child);
return !children.isEmpty();
}
}
public void clear() {
}
public void setProfile(CstProfile aProfile) {
this.aProfile = aProfile;
this.treeviewer.setInput(CstStateItem.getRootItems(aProfile));
}
/**
* class to display the execution of the heart beat
* with a pulsating heart (what else?)
* @author daniel
*
*/
public class HeartbeatThread extends Thread {
int pulse = 300;
public void run() {
try {
HeartbeatThread.sleep(1000);
UiDesk.asyncExec(new Runnable() {
public void run() {
lblCheckingForActions.setVisible(true);
lblHeart.setVisible(true);
}
});
for (final Image image : imageList) {
HeartbeatThread.sleep(pulse);
UiDesk.asyncExec(new Runnable() {
public void run() {
lblHeart.setImage(image);
}
});
}
UiDesk.asyncExec(new Runnable() {
public void run() {
lblCheckingForActions.setVisible(false);
lblHeart.setVisible(false);
}
});
HeartbeatThread.sleep(400);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}