/*******************************************************************************
* Copyright (c) 2007-2015, D. Lutz 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:
* D. Lutz - initial API and implementation
* Gerry Weirich - adapted for 2.1
* Niklaus Giger - small improvements, split into 20 classes
*
* Sponsors:
* Dr. Peter Schönbucher, Luzern
******************************************************************************/
package org.iatrix.widgets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Hashtable;
import java.util.List;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Text;
import org.iatrix.Iatrix;
import org.iatrix.actions.IatrixEventHelper;
import org.iatrix.data.Problem;
import org.iatrix.util.Constants;
import org.iatrix.util.DateComparator;
import org.iatrix.util.NumberComparator;
import org.iatrix.util.StatusComparator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.elexis.core.data.activator.CoreHub;
import ch.elexis.core.ui.UiDesk;
import ch.elexis.data.Patient;
import ch.elexis.data.PersistentObject;
import ch.elexis.data.Prescription;
import ch.elexis.icpc.Episode;
import ch.rgw.tools.StringTool;
import ch.rgw.tools.TimeTool;
import de.kupzog.ktable.KTable;
import de.kupzog.ktable.KTableCellEditor;
import de.kupzog.ktable.KTableCellRenderer;
import de.kupzog.ktable.KTableModel;
import de.kupzog.ktable.renderers.FixedCellRenderer;
public class ProblemsTableModel implements KTableModel {
private Patient actPatient;
private static Logger log = LoggerFactory.getLogger(ProblemsTableModel.class);
private MyKTable problemsKTable;
private Color highlightColor;
private ProblemsTableColorProvider problemsTableColorProvider = new ProblemsTableColorProvider();
private Object[] problems = null;
private final Hashtable<Integer, Integer> colWidths = new Hashtable<>();
private final Hashtable<Integer, Integer> rowHeights = new Hashtable<>();
private final KTableCellRenderer fixedRenderer =
new FixedCellRenderer(FixedCellRenderer.STYLE_PUSH | FixedCellRenderer.INDICATION_SORT
| FixedCellRenderer.INDICATION_FOCUS | FixedCellRenderer.INDICATION_CLICKED);
private final KTableCellRenderer textRenderer = new ProblemsTableTextCellRenderer();
private final KTableCellRenderer imageRenderer = new ProblemsTableImageCellRenderer();
private final KTableCellRenderer therapyRenderer = new ProblemsTableTherapyCellRenderer();
private static final DateComparator DATE_COMPARATOR = new DateComparator();
private static final NumberComparator NUMBER_COMPARATOR = new NumberComparator();
private static final StatusComparator STATUS_COMPARATOR = new StatusComparator();
private static Comparator<Problem> comparator = new DateComparator();
private boolean highlightSelection = false;
private boolean highlightRow = false;
public void refresh(){
// problemsKTable.updateScrollbarVisibility();
problemsKTable.redraw();
}
/**
* Base class for our cell editors Especially, we need to take care of heartbeat management
*/
abstract class BaseCellEditor extends KTableCellEditor {
@Override
public void open(KTable table, int col, int row, Rectangle rect){
org.iatrix.util.Heartbeat.getInstance().setHeartbeatProblemEnabled(false);
super.open(table, col, row, rect);
}
@Override
public void close(boolean save){
super.close(save);
org.iatrix.util.Heartbeat.getInstance().setHeartbeatProblemEnabled(true);
}
}
/**
* Replacement for KTableCellEditorText2 We don't want to have the editor vertically centered
*
* @author danlutz
*
*/
public class MyKTableCellEditorText2 extends BaseCellEditor {
protected Text m_Text;
protected KeyAdapter keyListener = new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e){
try {
onKeyPressed(e);
} catch (Exception ex) {
ex.printStackTrace();
// Do nothing
}
}
};
protected TraverseListener travListener = new TraverseListener() {
@Override
public void keyTraversed(TraverseEvent e){
onTraverse(e);
}
};
@Override
public void open(KTable table, int col, int row, Rectangle rect){
super.open(table, col, row, rect);
m_Text.setText(m_Model.getContentAt(m_Col, m_Row).toString());
m_Text.selectAll();
m_Text.setVisible(true);
m_Text.setFocus();
}
@Override
public void close(boolean save){
if (save)
m_Model.setContentAt(m_Col, m_Row, m_Text.getText());
m_Text.removeKeyListener(keyListener);
m_Text.removeTraverseListener(travListener);
super.close(save);
m_Text = null;
}
@Override
protected Control createControl(){
m_Text = new Text(m_Table, SWT.NONE);
m_Text.addKeyListener(keyListener);
m_Text.addTraverseListener(travListener);
return m_Text;
}
/**
* Implement In-Textfield navigation with the keys...
*
* @see de.kupzog.ktable.KTableCellEditor#onTraverse(org.eclipse.swt.events.TraverseEvent)
*/
@Override
protected void onTraverse(TraverseEvent e){
if (e.keyCode == SWT.ARROW_LEFT) {
// handel the event within the text widget!
} else if (e.keyCode == SWT.ARROW_RIGHT) {
// handle the event within the text widget!
} else
super.onTraverse(e);
}
@Override
protected void onKeyPressed(KeyEvent e){
if ((e.character == '\r') && ((e.stateMask & SWT.SHIFT) == 0)) {
close(true);
// move one row below!
// if (m_Row<m_Model.getRowCount())
// m_Table.setSelection(m_Col, m_Row+1, true);
} else
super.onKeyPressed(e);
}
/*
* (non-Javadoc)
*
* @see de.kupzog.ktable.KTableCellEditor#setContent(java.lang.Object)
*/
@Override
public void setContent(Object content){
m_Text.setText(content.toString());
m_Text.setSelection(content.toString().length());
}
}
public class KTableDiagnosisCellEditor extends BaseCellEditor {
private Combo combo;
private final KeyAdapter keyListener = new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e){
try {
onKeyPressed(e);
} catch (Exception ex) {
// Do nothing
}
}
};
private final TraverseListener travListener = new TraverseListener() {
@Override
public void keyTraversed(TraverseEvent e){
onTraverse(e);
}
};
@Override
public void open(KTable table, int col, int row, Rectangle rect){
super.open(table, col, row, rect);
String text = "";
Object obj = m_Model.getContentAt(m_Col, m_Row);
if (obj instanceof Problem) {
text = "test";
}
combo.setText(text);
combo.setVisible(true);
combo.setFocus();
}
@Override
public void close(boolean save){
if (save)
m_Model.setContentAt(m_Col, m_Row, combo.getText());
combo.removeKeyListener(keyListener);
combo.removeTraverseListener(travListener);
combo = null;
super.close(save);
}
@Override
protected Control createControl(){
combo = new Combo(m_Table, SWT.DROP_DOWN);
combo.addKeyListener(keyListener);
combo.addTraverseListener(travListener);
return combo;
}
/**
* Implement In-Textfield navigation with the keys...
*
* @see de.kupzog.ktable.KTableCellEditor#onTraverse(org.eclipse.swt.events.TraverseEvent)
*/
@Override
protected void onTraverse(TraverseEvent e){
if (e.keyCode == SWT.ARROW_LEFT) {
// handel the event within the text widget!
} else if (e.keyCode == SWT.ARROW_RIGHT) {
// handle the event within the text widget!
} else
super.onTraverse(e);
}
/*
* overridden from superclass
*/
@Override
public void setBounds(Rectangle rect){
super.setBounds(new Rectangle(rect.x, rect.y, rect.width, rect.height));
}
/*
* (non-Javadoc)
*
* @see de.kupzog.ktable.KTableCellEditor#setContent(java.lang.Object)
*/
@Override
public void setContent(Object content){
combo.setText(content.toString());
}
}
public class KTableTherapyCellEditor extends BaseCellEditor {
private Text m_Text;
private final KeyAdapter keyListener = new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e){
try {
onKeyPressed(e);
} catch (Exception ex) {
// Do nothing
}
}
};
private final TraverseListener travListener = new TraverseListener() {
@Override
public void keyTraversed(TraverseEvent e){
onTraverse(e);
}
};
@Override
public void open(KTable table, int col, int row, Rectangle rect){
super.open(table, col, row, rect);
String text = "";
Object obj = m_Model.getContentAt(m_Col, m_Row);
if (obj instanceof Problem) {
Problem problem = (Problem) obj;
text = problem.getProcedere();
}
m_Text.setText(PersistentObject.checkNull(text));
m_Text.selectAll();
m_Text.setVisible(true);
m_Text.setFocus();
}
@Override
public void close(boolean save){
if (save)
m_Model.setContentAt(m_Col, m_Row, m_Text.getText());
m_Text.removeKeyListener(keyListener);
m_Text.removeTraverseListener(travListener);
m_Text = null;
super.close(save);
}
@Override
protected Control createControl(){
m_Text = new Text(m_Table, SWT.MULTI | SWT.V_SCROLL);
m_Text.addKeyListener(keyListener);
m_Text.addTraverseListener(travListener);
return m_Text;
}
/**
* Implement In-Textfield navigation with the keys...
*
* @see de.kupzog.ktable.KTableCellEditor#onTraverse(org.eclipse.swt.events.TraverseEvent)
*/
@Override
protected void onTraverse(TraverseEvent e){
if (e.keyCode == SWT.ARROW_LEFT) {
// handel the event within the text widget!
} else if (e.keyCode == SWT.ARROW_RIGHT) {
// handle the event within the text widget!
} else
super.onTraverse(e);
}
/*
* overridden from superclass
*/
@Override
public void setBounds(Rectangle rect){
super.setBounds(new Rectangle(rect.x, rect.y, rect.width, rect.height));
}
/*
* (non-Javadoc)
*
* @see de.kupzog.ktable.KTableCellEditor#setContent(java.lang.Object)
*/
@Override
public void setContent(Object content){
m_Text.setText(content.toString());
m_Text.setSelection(content.toString().length());
}
}
class ProblemsTableImageCellRenderer extends ProblemsTableCellRendererBase {
private final Display display;
public ProblemsTableImageCellRenderer(){
display = Display.getCurrent();
}
@Override
public int getOptimalWidth(GC gc, int col, int row, Object content, boolean fixed,
KTableModel model){
if (content instanceof Image) {
Image image = (Image) content;
return image.getBounds().width;
} else {
return 0;
}
}
@Override
public void drawCell(GC gc, Rectangle rect, int col, int row, Object content, boolean focus,
boolean fixed, boolean clicked, KTableModel model){
Color backColor;
Color borderColor;
Image image = null;
if (content instanceof Image) {
image = (Image) content;
}
if (isSelected(row) && ((ProblemsTableModel) model).isHighlightRow()) {
backColor = highlightColor;
} else if (focus && ((ProblemsTableModel) model).isHighlightSelection()) {
backColor = highlightColor;
} else {
backColor = display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
}
borderColor = display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
gc.setForeground(borderColor);
gc.drawLine(rect.x, rect.y + rect.height, rect.x + rect.width, rect.y + rect.height);
gc.setForeground(borderColor);
gc.drawLine(rect.x + rect.width, rect.y, rect.x + rect.width, rect.y + rect.height);
gc.setBackground(backColor);
gc.fillRectangle(rect);
if (image != null) {
// center image
Rectangle imageBounds = image.getBounds();
int imageWidth = imageBounds.width;
int imageHeight = imageBounds.height;
int xOffset = (rect.width - imageWidth) / 2;
int yOffset = (rect.height - imageHeight) / 2;
Rectangle oldClipping = gc.getClipping();
gc.setClipping(rect);
gc.drawImage(image, rect.x + xOffset, rect.y + yOffset);
gc.setClipping(oldClipping);
}
if (focus) {
gc.drawFocus(rect.x, rect.y, rect.width, rect.height);
}
}
}
abstract class ProblemsTableCellRendererBase implements KTableCellRenderer {
protected Problem getSelectedProblem(){
Point[] selection = problemsKTable.getCellSelection();
if (selection == null || selection.length == 0) {
return null;
} else {
int rowIndex = selection[0].y - getFixedHeaderRowCount();
Problem problem = getProblem(rowIndex);
return problem;
}
}
protected boolean isSelected(int row){
if (problemsKTable.isRowSelectMode()) {
int[] selectedRows = problemsKTable.getRowSelection();
if (selectedRows != null) {
for (int r : selectedRows) {
if (r == row) {
return true;
}
}
}
} else {
Point[] selectedCells = problemsKTable.getCellSelection();
if (selectedCells != null) {
for (Point cell : selectedCells) {
if (cell.y == row) {
return true;
}
}
}
}
return false;
}
}
class ProblemsTableTextCellRenderer extends ProblemsTableCellRendererBase {
private final Display display;
public ProblemsTableTextCellRenderer(){
display = Display.getCurrent();
}
@Override
public int getOptimalWidth(GC gc, int col, int row, Object content, boolean fixed,
KTableModel model){
if (content instanceof String) {
String text = (String) content;
return gc.textExtent(text).x + 8;
} else {
return 0;
}
}
@Override
public void drawCell(GC gc, Rectangle rect, int col, int row, Object content, boolean focus,
boolean fixed, boolean clicked, KTableModel model){
Color textColor;
Color backColor;
Color borderColor;
String text;
if (content instanceof String) {
text = (String) content;
} else {
text = "";
}
if (focus) {
textColor = display.getSystemColor(SWT.COLOR_BLUE);
} else {
textColor = problemsTableColorProvider.getForegroundColor(col, row);
}
if (isSelected(row) && ((ProblemsTableModel) model).isHighlightRow()) {
backColor = highlightColor;
} else if (focus && ((ProblemsTableModel) model).isHighlightSelection()) {
backColor = highlightColor;
} else {
backColor = display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
}
borderColor = display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
gc.setForeground(borderColor);
gc.drawLine(rect.x, rect.y + rect.height, rect.x + rect.width, rect.y + rect.height);
gc.setForeground(borderColor);
gc.drawLine(rect.x + rect.width, rect.y, rect.x + rect.width, rect.y + rect.height);
gc.setBackground(backColor);
gc.setForeground(textColor);
gc.fillRectangle(rect);
Rectangle oldClipping = gc.getClipping();
gc.setClipping(rect);
gc.drawText((text), rect.x + 3, rect.y);
gc.setClipping(oldClipping);
if (focus) {
gc.drawFocus(rect.x, rect.y, rect.width, rect.height);
}
}
}
/**
* Renderer for Therapy cell. Shows the procedere of the problem. If there are prescriptions,
* they are shown above the procedere, separated by a line.
*
* @author danlutz
*/
class ProblemsTableTherapyCellRenderer extends ProblemsTableCellRendererBase {
private static final int MARGIN = 8;
private static final int PADDING = 3;
private final Display display;
public ProblemsTableTherapyCellRenderer(){
display = Display.getCurrent();
}
private boolean hasPrescriptions(Problem problem){
List<Prescription> prescriptions = problem.getPrescriptions();
return (prescriptions.size() > 0);
}
private boolean hasProcedere(Problem problem){
if (!StringTool.isNothing(PersistentObject.checkNull(problem.getProcedere()))) {
return true;
} else {
return false;
}
}
private String getPrescriptionsText(Problem problem){
String prescriptions = PersistentObject.checkNull(problem.getPrescriptionsAsText());
String lineSeparator = System.getProperty("line.separator");
String prescriptionsText =
prescriptions.replaceAll(Problem.TEXT_SEPARATOR, lineSeparator);
return prescriptionsText;
}
private String getProcedereText(Problem problem){
return PersistentObject.checkNull(problem.getProcedere());
}
public int getOptimalHeight(GC gc, Problem problem){
int height = 0;
int prescriptionsHeight = 0;
if (hasPrescriptions(problem)) {
String prescriptionsText = getPrescriptionsText(problem);
prescriptionsHeight = gc.textExtent(prescriptionsText).y;
}
int procedereHeight = 0;
if (hasProcedere(problem)) {
String procedereText = getProcedereText(problem);
procedereHeight = gc.textExtent(procedereText).y;
}
if (prescriptionsHeight > 0 && procedereHeight > 0) {
height = prescriptionsHeight + PADDING + procedereHeight;
} else if (prescriptionsHeight > 0) {
height = prescriptionsHeight;
} else if (procedereHeight > 0) {
height = procedereHeight;
}
if (height == 0) {
// default height
height = gc.textExtent("").y;
}
return height;
}
@Override
public int getOptimalWidth(GC gc, int col, int row, Object content, boolean fixed,
KTableModel model){
if (content instanceof Problem) {
Problem problem = (Problem) content;
String prescriptionsText = getPrescriptionsText(problem);
String procedereText = getProcedereText(problem);
int width1 = gc.textExtent(prescriptionsText).x;
int width2 = gc.textExtent(procedereText).x;
int width = Math.max(width1, width2);
return width + MARGIN;
} else {
return 0;
}
}
@Override
public void drawCell(GC gc, Rectangle rect, int col, int row, Object content, boolean focus,
boolean fixed, boolean clicked, KTableModel model){
Color textColor;
Color backColor;
Color borderColor;
String prescriptionsText = "";
String procedereText = "";
boolean hasPrescriptions = false;
boolean hasProcedere = false;
if (content instanceof Problem) {
Problem problem = (Problem) content;
prescriptionsText = getPrescriptionsText(problem);
procedereText = getProcedereText(problem);
hasPrescriptions = hasPrescriptions(problem);
hasProcedere = hasProcedere(problem);
}
if (focus) {
textColor = display.getSystemColor(SWT.COLOR_BLUE);
} else {
textColor = problemsTableColorProvider.getForegroundColor(col, row);
}
if (isSelected(row) && ((ProblemsTableModel) model).isHighlightRow()) {
backColor = highlightColor;
} else if (focus && ((ProblemsTableModel) model).isHighlightSelection()) {
backColor = highlightColor;
} else {
backColor = display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
}
borderColor = display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
gc.setForeground(borderColor);
gc.drawLine(rect.x, rect.y + rect.height, rect.x + rect.width, rect.y + rect.height);
gc.setForeground(borderColor);
gc.drawLine(rect.x + rect.width, rect.y, rect.x + rect.width, rect.y + rect.height);
gc.setBackground(backColor);
gc.setForeground(textColor);
gc.fillRectangle(rect);
Rectangle oldClipping = gc.getClipping();
gc.setClipping(rect);
if (hasPrescriptions && hasProcedere) {
// draw prescriptions and procedre, separated by a line
int prescriptionsHeight = gc.textExtent(prescriptionsText).y;
gc.setForeground(borderColor);
gc.drawLine(rect.x, rect.y + prescriptionsHeight + 1, rect.x + rect.width,
rect.y + prescriptionsHeight + 1);
gc.setBackground(backColor);
gc.setForeground(textColor);
gc.drawText(prescriptionsText, rect.x + 3, rect.y);
gc.drawText(procedereText, rect.x + 3, rect.y + prescriptionsHeight + PADDING);
} else {
String text;
if (hasPrescriptions) {
// prescriptions only
text = prescriptionsText;
} else if (hasProcedere) {
// procedere only
text = procedereText;
} else {
// nothing
text = "";
}
gc.setBackground(backColor);
gc.setForeground(textColor);
gc.drawText(text, rect.x + 3, rect.y);
}
gc.setClipping(oldClipping);
if (focus) {
gc.drawFocus(rect.x, rect.y, rect.width, rect.height);
}
}
}
/*
* Heartbeat activation management The heartbeat events are only processed if these variables
* are set to true. They may be set to false if heartbeat processing would distrub, e. g. in
* case of editing a problem or the consultation text.
*/
private boolean heartbeatProblemEnabled = true;
public void heartbeatProblem(){
log.debug("heartbeatProblem enabled " + heartbeatProblemEnabled);
if (heartbeatProblemEnabled) {
// backup selection
boolean isRowSelectMode = problemsKTable.isRowSelectMode();
Problem selectedProblem = null;
int currentColumn = -1;
if (isRowSelectMode) {
// full row selection
// not supported
} else {
// single cell selection
Point[] cells = problemsKTable.getCellSelection();
if (cells != null && cells.length > 0) {
int row = cells[0].y;
int rowIndex = row - getFixedHeaderRowCount();
selectedProblem = getProblem(rowIndex);
currentColumn = cells[0].x;
}
}
// restore selection
if (selectedProblem != null) {
if (isRowSelectMode) {
// full row selection
// not supported
} else {
// single cell selection
int rowIndex = getIndexOf(selectedProblem);
if (rowIndex >= 0) {
// problem found, i. e. still in list
int row = rowIndex + getFixedHeaderRowCount();
if (currentColumn == -1) {
currentColumn = getFixedHeaderColumnCount();
}
problemsKTable.setSelection(currentColumn, row, true);
}
}
}
}
}
public Problem getProblem(int index){
Problem problem = null;
if (problems != null) {
if (index >= 0 && index < problems.length) {
Object element = problems[index];
if (element instanceof Problem) {
problem = (Problem) element;
}
}
}
return problem;
}
/**
* Finds the index of the given problem (array index, not row)
*
* @param problem
* @return the index, or -1 if not found
*/
public int getIndexOf(Problem problem){
if (problems != null) {
for (int i = 0; i < problems.length; i++) {
Object element = problems[i];
if (element instanceof Problem) {
Problem p = (Problem) element;
if (p.getId().equals(problem.getId())) {
return i;
}
}
}
}
return -1;
}
/**
* Returns the KTable index corresponding to our model index (mapping)
*
* @param rowIndex
* the index of a problem
* @return the problem's index as a KTable index
*/
public int modelIndexToTableIndex(int rowIndex){
return rowIndex + getFixedHeaderRowCount();
}
/**
* Returns the model index corresponding to the KTable index (mapping)
*
* @param row
* the KTable index of a problem
* @return the problem's index of the model
*/
public int tableIndexToRowIndex(int row){
return row - getFixedHeaderRowCount();
}
@Override
public Point belongsToCell(int col, int row){
return new Point(col, row);
}
@Override
public KTableCellEditor getCellEditor(int col, int row){
if (row < getFixedHeaderRowCount() || col < getFixedHeaderColumnCount()) {
return null;
}
int colIndex = col - getFixedHeaderColumnCount();
if (colIndex == Constants.BEZEICHNUNG || colIndex == Constants.NUMMER
|| colIndex == Constants.DATUM) {
return new MyKTableCellEditorText2();
} else if (colIndex == Constants.THERAPIE) {
return new KTableTherapyCellEditor();
} else {
return null;
}
}
@Override
public KTableCellRenderer getCellRenderer(int col, int row){
if (row < getFixedHeaderRowCount() || col < getFixedHeaderColumnCount()) {
return fixedRenderer;
}
int colIndex = col - getFixedHeaderColumnCount();
if (colIndex == Constants.STATUS) {
return imageRenderer;
}
if (colIndex == Constants.THERAPIE) {
return therapyRenderer;
}
return textRenderer;
}
@Override
public int getColumnCount(){
return getFixedHeaderColumnCount() + Constants.COLUMN_TEXT.length;
}
@Override
public int getRowCount(){
loadElements();
return getFixedHeaderRowCount() + problems.length;
}
@Override
public int getFixedHeaderColumnCount(){
return 1;
}
@Override
public int getFixedSelectableColumnCount(){
return 0;
}
@Override
public int getFixedHeaderRowCount(){
return 1;
}
@Override
public int getFixedSelectableRowCount(){
return 0;
}
private int getInitialColumnWidth(int col){
if (col < getFixedHeaderColumnCount()) {
return 20;
}
int colIndex = col - getFixedHeaderColumnCount();
if (colIndex >= 0 && colIndex < Constants.COLUMN_TEXT.length) {
int width =
CoreHub.localCfg.get(Constants.COLUMN_CFG_KEY[colIndex], Constants.DEFAULT_COLUMN_WIDTH[colIndex]);
return width;
} else {
// invalid column
return 0;
}
}
@Override
public int getColumnWidth(int col){
Integer width = colWidths.get(new Integer(col));
if (width == null) {
width = new Integer(getInitialColumnWidth(col));
colWidths.put(new Integer(col), width);
}
return width.intValue();
}
private int getHeaderRowHeight(){
// TODO
return 22;
}
@Override
public int getRowHeightMinimum(){
// TODO
return 10;
}
@Override
public int getRowHeight(int row){
Integer height = rowHeights.get(new Integer(row));
if (height == null) {
height = new Integer(getOptimalRowHeight(row));
rowHeights.put(new Integer(row), height);
}
return height.intValue();
}
private int getOptimalRowHeight(int row){
if (row < getFixedHeaderRowCount()) {
return getHeaderRowHeight();
} else {
int height = 0;
GC gc = new GC(problemsKTable);
for (int i = 0; i < Constants.COLUMN_TEXT.length; i++) {
int col = i + getFixedHeaderColumnCount();
int currentHeight = 0;
Object obj = getContentAt(col, row);
if (obj instanceof String) {
String text = (String) obj;
currentHeight = gc.textExtent(text).y;
} else if (obj instanceof Image) {
Image image = (Image) obj;
currentHeight = image.getBounds().height;
} else if (obj instanceof Problem && i == Constants.THERAPIE) {
Problem problem = (Problem) obj;
ProblemsTableTherapyCellRenderer cellRenderer =
(ProblemsTableTherapyCellRenderer) getCellRenderer(col, row);
currentHeight = cellRenderer.getOptimalHeight(gc, problem);
}
if (currentHeight > height) {
height = currentHeight;
}
}
gc.dispose();
return height;
}
}
@Override
public void setColumnWidth(int col, int width){
colWidths.put(new Integer(col), new Integer(width));
// store new column with in localCfg
int colIndex = col - getFixedHeaderColumnCount();
if (colIndex >= 0 && colIndex < Constants.COLUMN_TEXT.length) {
CoreHub.localCfg.set(Constants.COLUMN_CFG_KEY[colIndex], width);
}
}
@Override
public void setRowHeight(int row, int height){
rowHeights.put(new Integer(row), new Integer(height));
}
private void loadElements(){
if (problems == null) {
List<Object> elements = new ArrayList<>();
if (actPatient != null) {
List<Problem> problems = Problem.getProblemsOfPatient(actPatient);
if (comparator != null) {
Collections.sort(problems, comparator);
}
elements.addAll(problems);
// add dummy element
elements.add(new DummyProblem());
}
problems = elements.toArray();
}
}
private void addElement(Object element){
Object[] newProblems = new Object[problems.length + 1];
System.arraycopy(problems, 0, newProblems, 0, problems.length);
newProblems[newProblems.length - 1] = element;
}
public void reload(){
// force elements to be reloaded
problems = null;
// force heights to be re-calculated
rowHeights.clear();
}
private Object getHeaderContentAt(int col){
int colIndex = col - getFixedHeaderColumnCount();
if (colIndex >= 0 && colIndex < Constants.COLUMN_TEXT.length) {
return Constants.COLUMN_TEXT[colIndex];
} else {
return "";
}
}
@Override
public Object getContentAt(int col, int row){
if (row < getFixedHeaderRowCount()) {
// header
return getHeaderContentAt(col);
}
// rows
// load problems if required
loadElements();
int colIndex = col - getFixedHeaderColumnCount();
int rowIndex = row - getFixedHeaderRowCount(); // consider header row
if (rowIndex >= 0 && rowIndex < problems.length) {
Object element = problems[rowIndex];
if (element instanceof Problem) {
Problem problem = (Problem) element;
String text;
String lineSeparator;
switch (colIndex) {
case Constants.BEZEICHNUNG:
return problem.getTitle();
case Constants.NUMMER:
return problem.getNumber();
case Constants.DATUM:
return problem.getStartDate();
case Constants.DIAGNOSEN:
String diagnosen = problem.getDiagnosenAsText();
lineSeparator = System.getProperty("line.separator");
text = diagnosen.replaceAll(Problem.TEXT_SEPARATOR, lineSeparator);
return text;
/*
* case GESETZ: return problem.getGesetz();
*/
/*
* case RECHNUNGSDATEN: return "not yet implemented";
*/
case Constants.THERAPIE:
/*
* String prescriptions = problem.getPrescriptionsAsText(); lineSeparator =
* System.getProperty("line.separator"); text =
* prescriptions.replaceAll(Problem.TEXT_SEPARATOR, lineSeparator); return
* text;
*/
return problem;
/*
* case PROCEDERE: return problem.getProcedere();
*/
case Constants.STATUS:
if (problem.getStatus() == Episode.ACTIVE) {
return UiDesk.getImage(Iatrix.IMG_ACTIVE);
} else {
return UiDesk.getImage(Iatrix.IMG_INACTIVE);
}
default:
return "";
}
} else {
// DummyProblem
if (col < getFixedHeaderColumnCount()) {
return "*";
} else {
return "";
}
}
} else {
// row index out of bound
return "";
}
}
@Override
public String getTooltipAt(int col, int row){
if (col < Constants.TOOLTIP_TEXT.length)
return Constants.TOOLTIP_TEXT[col];
else
return "Tooltip für col " + col;
}
@Override
public boolean isColumnResizable(int col){
return true;
}
@Override
public boolean isRowResizable(int row){
return true;
}
@Override
public void setContentAt(int col, int row, Object value){
// don't do anything if there are no problems
if (problems == null) {
return;
}
// only accept String values
if (!(value instanceof String)) {
return;
}
String text = (String) value;
int colIndex = col - getFixedHeaderColumnCount();
int rowIndex = row - getFixedHeaderRowCount();
if (rowIndex >= 0 && rowIndex < problems.length) {
boolean isNew = false;
Problem problem;
if (problems[rowIndex] instanceof Problem) {
problem = (Problem) problems[rowIndex];
} else {
// replace dummy object with real object
if (actPatient == null) {
// shuldn't happen; silently ignore
return;
}
problem = new Problem(actPatient, "");
String currentDate = new TimeTool().toString(TimeTool.DATE_ISO);
problem.setStartDate(currentDate);
IatrixEventHelper.fireSelectionEventProblem(problem);
problems[rowIndex] = problem;
addElement(new DummyProblem());
isNew = true;
}
switch (colIndex) {
case Constants.BEZEICHNUNG:
problem.setTitle(text);
break;
case Constants.NUMMER:
problem.setNumber(text);
break;
case Constants.DATUM:
problem.setStartDate(text);
break;
case Constants.THERAPIE:
problem.setProcedere(text);
break;
}
if (isNew) {
reload();
refresh();
// TODO: ngng
problemsKTable.refresh();
}
}
}
public void setComparator(int col, int row){
if (row < getFixedHeaderRowCount()) {
int colIndex = col - getFixedHeaderColumnCount();
switch (colIndex) {
case Constants.DATUM:
comparator = DATE_COMPARATOR;
break;
case Constants.NUMMER:
comparator = NUMBER_COMPARATOR;
break;
case Constants.STATUS:
comparator = STATUS_COMPARATOR;
break;
}
}
}
public void setHighlightSelection(boolean highlight, boolean row){
this.highlightSelection = highlight;
this.highlightRow = row;
}
public boolean isHighlightSelection(){
return highlightSelection;
}
public boolean isHighlightRow(){
return highlightSelection && highlightRow;
}
class ProblemsTableColorProvider {
public Color getForegroundColor(int col, int row){
int rowIndex = row - getFixedHeaderRowCount();
Problem problem = getProblem(rowIndex);
if (problem != null && problem.getStatus() == Episode.ACTIVE) {
return Display.getCurrent().getSystemColor(SWT.COLOR_BLACK);
} else {
return Display.getCurrent().getSystemColor(SWT.COLOR_GRAY);
}
}
}
public KTable getProblemsKTable(){
return problemsKTable;
}
public void setProblemsKTable(MyKTable problemsKTable2){
problemsKTable = problemsKTable2;
}
static class DummyProblem {}
public void setPatient(Patient newPatient){
actPatient = newPatient;
}
}