Java tutorial
/******************************************************************************* * Copyright (c) 2005-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 * *******************************************************************************/ package ch.elexis.views; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Hashtable; import java.util.LinkedList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; 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.IToolBarManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.ControlEditor; import org.eclipse.swt.custom.TableCursor; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IActionBars; import org.eclipse.ui.ISaveablePart2; import org.eclipse.ui.forms.widgets.Form; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.part.ViewPart; import org.eclipse.ui.statushandlers.StatusManager; import org.jdom.Document; import org.jdom.Element; import org.jdom.output.Format; import org.jdom.output.XMLOutputter; import ch.elexis.Desk; import ch.elexis.ElexisException; import ch.elexis.Hub; import ch.elexis.actions.ElexisEvent; import ch.elexis.actions.ElexisEventDispatcher; import ch.elexis.actions.ElexisEventListener; import ch.elexis.actions.ElexisEventListenerImpl; import ch.elexis.actions.GlobalActions; import ch.elexis.actions.GlobalEventDispatcher; import ch.elexis.actions.GlobalEventDispatcher.IActivationListener; import ch.elexis.core.icons.Images; import ch.elexis.data.Konsultation; import ch.elexis.data.LabItem; import ch.elexis.data.LabResult; import ch.elexis.data.Patient; import ch.elexis.data.PersistentObject; import ch.elexis.data.Person; import ch.elexis.data.Query; import ch.elexis.dialogs.DateSelectorDialog; import ch.elexis.dialogs.DisplayLabDokumenteDialog; import ch.elexis.dialogs.DisplayTextDialog; import ch.elexis.util.Extensions; import ch.elexis.util.Importer; import ch.elexis.util.Log; import ch.elexis.util.SWTHelper; import ch.elexis.util.ViewMenus; import ch.rgw.tools.ExHandler; import ch.rgw.tools.JdbcLink.Stm; import ch.rgw.tools.TimeTool; /** * Anzeige von Laboritems und Anzeige und Eingabemglichkeit von Laborwerten. * * Der Algorithmus geht so: Zuerst werden alle Laboritems eingesammelt und gemss ihren Gruppen und * Prioritten sortiert (nur beim create) Beim Einlesen eines neuen Patienten werden zunchst alle * Daten gesammelt, an denen fr diesen Patienten Laborwerte vorliegen. Diese werden nach Alter * sortiert und mit den jeweiligen Laborwerten zusammengefasst. Jeweils NUMCOLUMNS Daten werden auf * einer Anzeigeseite angezeigt. Der Anwender kann auf den Seiten blttern, aber es werden alle * Laborwerte des aktuellen Patienten im Speicher gehalten. * * @author gerry */ public class LaborView extends ViewPart implements IActivationListener, ISaveablePart2 { private static final String KEY_TEXT = "Text"; //$NON-NLS-1$ private static final String PATTERN_DECIMAL = "[0-9\\.]+"; //$NON-NLS-1$ private static final String KEY_VALUES = "Values"; //$NON-NLS-1$ private static final String KEY_ITEM = "Item"; //$NON-NLS-1$ public static final String ID = "ch.elexis.Labor"; //$NON-NLS-1$ private static final String ICON = "labor_view"; //$NON-NLS-1$ private static Log log = Log.get("LaborView"); //$NON-NLS-1$ final static int NUMCOLUMNS = 7; // Pro Seite angezeigte Laborspalten final static int COL_OFFSET = 2; // Fr Information bentigte Spalten final static Color COL_PATHOLOGIC = Desk.getColor(Desk.COL_RED); final static Color COL_REMARK = Desk.getColor(Desk.COL_BLUE); final static Color COL_BACKGND = Desk.getColor(Desk.COL_WHITE); int actPage; // Aktuell angezeigte Seite int firstColumn, lastColumn; // Erste und letzte Datumspalte der // aktuellen Seite Patient actPatient; // Aktuell ausgewhlter Patient /* Tabelle */ Table table; TableColumn[] columns; TableItem[] rows; TableCursor cursor; ControlEditor editor; private Hashtable<String, List<LabItem>> hGroups; // Gruppen von // Laboritems private Hashtable<String, Integer> hLabItems; // Mapping von Laboritems // auf Tabellenzeilen List<String> lGroupNames; // Alphabetische Gruppenliste // List<LabResult> lResults; String[] sDaten; // Sortierte Liste aller Daten von Laborresultaten Hashtable<String, Integer> hDaten; // Mapping von Datum auf Tabellenspalten private Action fwdAction, backAction, printAction, importAction, xmlAction, newAction, setStateAction, refreshAction; private ViewMenus menu; private final FormToolkit tk = Desk.getToolkit(); private Form form; // Formula handling private final static Pattern varsPattern = Pattern.compile("[a-zA-Z0-9]+_[0-9]+"); //$NON-NLS-1$ private final HashMap<String, List<LabItem>> formulaRelations = new HashMap<String, List<LabItem>>(); private ElexisEventListenerImpl eeli_pat = new ElexisEventListenerImpl(Patient.class) { public void runInUi(ElexisEvent ev) { selectPatient((Patient) ev.getObject()); } }; private ElexisEventListener eeli_labitem = new ElexisEventListener() { private final ElexisEvent eetmpl = new ElexisEvent(null, LabItem.class, ElexisEvent.EVENT_RELOAD); public ElexisEvent getElexisEventFilter() { return eetmpl; } public void catchElexisEvent(ElexisEvent ev) { Desk.getDisplay().asyncExec(new Runnable() { public void run() { rebuild(); } }); } }; @Override public void createPartControl(final Composite parent) { setTitleImage(Desk.getImage(ICON)); parent.setLayout(new GridLayout()); form = tk.createForm(parent); form.setLayoutData(SWTHelper.getFillGridData(1, true, 1, true)); Composite body = form.getBody(); body.setLayout(new GridLayout()); table = new Table(body, SWT.FULL_SELECTION | SWT.LEFT | SWT.V_SCROLL | SWT.H_SCROLL); table.setLayoutData(SWTHelper.getFillGridData(1, true, 1, true)); table.setHeaderVisible(true); table.setLinesVisible(true); table.addListener(SWT.PaintItem, new Listener() { private void paintCell(final String text, final Event event, final Color foregnd, final Color backgnd) { Point size = event.gc.textExtent(text); int offset1 = Math.max(0, (event.width - size.x) / 2); int offset2 = Math.max(0, (event.height - size.y) / 2); GC gc = event.gc; gc.setForeground(backgnd); gc.fillRectangle(event.x, event.y, event.width, event.height); gc.setForeground(foregnd); event.gc.drawText(text, event.x + offset1, event.y + offset2, true); } public void handleEvent(final Event event) { TableItem item = (TableItem) event.item; String text = item.getText(event.index); LabItem it = (LabItem) item.getData(KEY_ITEM); if (it != null) { LabResult[] lrs = (LabResult[]) item.getData(KEY_VALUES); if (lrs != null) { int screenIdx = event.index - COL_OFFSET; if ((screenIdx >= 0) && (screenIdx < lrs.length)) { LabResult lr = lrs[screenIdx]; if (lr != null) { if (lr.isFlag(LabResult.PATHOLOGIC)) { paintCell(text, event, COL_PATHOLOGIC, COL_BACKGND); } if (lr.getComment().length() > 0) { paintCell(text, event, COL_REMARK, COL_BACKGND); } } } } } } }); cursor = new TableCursor(table, SWT.NONE); editor = new ControlEditor(cursor); editor.grabHorizontal = true; editor.grabVertical = true; /* * Tastatursteuerung fr die Tabelle: Druck auf Eingabetaste lsst die Zelle editieren, * sofern sie auf einem editierbaren Feld ist. Wenn sie nicht auf einem editierbaren Feld * ist, wird der stattdessen Cursor eine Zeile nach unten bewegt. Druck auf irgendeine Zahl- * oder Buchstabentaste lsst die Zelle editieren, wenn sie editierbar ist. Editierbar ist * eine Zelle dann, wenn sie sich a) in einer Spalte mit einem Datum im Kopf befindet, und * b) sich in einer Zeile mit einem LaborItem am Anfang befindet. */ cursor.addSelectionListener(new SelectionAdapter() { // Tabellenauswahl soll dem Cursor folgen @Override public void widgetSelected(final SelectionEvent e) { table.setSelection(new TableItem[] { cursor.getRow() }); } // Eingabetaste @Override public void widgetDefaultSelected(final SelectionEvent e) { TableItem row = cursor.getRow(); LabItem li = (LabItem) row.getData(KEY_ITEM); if (li == null) { cursorDown(); return; } int column = cursor.getColumn(); if (columns[column].getText().matches(PATTERN_DECIMAL)) { doEdit(row.getText(column)); } } }); // Sonstige Taste cursor.addKeyListener(new KeyAdapter() { @Override public void keyPressed(final KeyEvent e) { if (e.character == SWT.DEL) { return; } TableItem row = cursor.getRow(); e.doit = false; if (row.getData(KEY_ITEM) == null) { return; } if (e.character > 0x30) { StringBuilder sb = new StringBuilder(); sb.append(e.character); int column = cursor.getColumn(); if (columns[column].getText().matches(PATTERN_DECIMAL)) { doEdit(sb.toString()); } } } }); cursor.addMouseListener(new MouseAdapter() { @Override public void mouseDoubleClick(final MouseEvent e) { LabResult lr = actResult(); if (lr != null) { LabItem li = lr.getItem(); if (li.getTyp().equals(LabItem.typ.TEXT) || (lr.getComment().length() > 0)) { DisplayTextDialog dlg = new DisplayTextDialog(getViewSite().getShell(), Messages.getString("LaborView.textResultTitle"), li.getName(), lr.getComment()); //$NON-NLS-1$ Font font = null; // HL7 Befunde enthalten oft mit Leerzeichen formatierte Bemerkungen, // die nur mit nicht-proportionalen Fonts dargestellt werden knnen // Wir versuchen also, die Anzeige mit Courier New, ohne zu wissen ob die // auf Mac und Linux auch drauf sind. // Falls der Font nicht geladen werden kann, wird der System-Default Font // verwendet // Hier die Fonts, welche getestet worden sind: // Windows: Courier New (getestet= // Mac: nicht getestet // Linux: nicht getestet try { font = new Font(null, "Courier New", 9, SWT.NORMAL); //$NON-NLS-1$ } catch (Exception ex) { // Do nothing -> Use System Default font } finally { dlg.setFont(font); } dlg.setWhitespaceNormalized(false); dlg.open(); } else if (li.getTyp().equals(LabItem.typ.DOCUMENT)) { Patient patient = ElexisEventDispatcher.getSelectedPatient(); if (patient != null) { Query<LabResult> labResultQuery = new Query<LabResult>(LabResult.class); labResultQuery.add(LabResult.PATIENT_ID, Query.EQUALS, patient.getId()); labResultQuery.add(LabResult.DATE, Query.EQUALS, lr.getDate()); labResultQuery.add(LabResult.ITEM_ID, Query.EQUALS, li.getId()); List<LabResult> labResultList = labResultQuery.execute(); if (labResultList != null && labResultList.size() > 0) { new DisplayLabDokumenteDialog(getViewSite().getShell(), Messages.getString("LaborView.Documents"), labResultList).open();//$NON-NLS-1$ } } } } super.mouseDoubleClick(e); } }); makeActions(); menu = new ViewMenus(getViewSite()); menu.createMenu(newAction, backAction, fwdAction, printAction, importAction, xmlAction); // Orders final LaborOrderPulldownMenuCreator menuCreator = new LaborOrderPulldownMenuCreator(parent.getShell()); if (menuCreator.getSelected() != null) { IAction dropDownAction = menuCreator.getAction(); IActionBars actionBars = getViewSite().getActionBars(); IToolBarManager toolbar = actionBars.getToolBarManager(); toolbar.add(dropDownAction); // Set data dropDownAction.setText(menuCreator.getSelected().getText()); dropDownAction.setToolTipText(menuCreator.getSelected().getToolTipText()); dropDownAction.setImageDescriptor(menuCreator.getSelected().getImageDescriptor()); } // Importers IToolBarManager tm = getViewSite().getActionBars().getToolBarManager(); List<IAction> importers = Extensions.getClasses(Extensions.getExtensions("ch.elexis.LaborDatenImport"), //$NON-NLS-1$ "ToolbarAction", //$NON-NLS-1$ false); for (IAction ac : importers) { tm.add(ac); } if (importers.size() > 0) { tm.add(new Separator()); } tm.add(refreshAction); tm.add(newAction); tm.add(backAction); tm.add(fwdAction); tm.add(printAction); // menu.createToolbar(newAction,backAction,fwdAction,printAction); final MenuManager mgr = new MenuManager("path"); //$NON-NLS-1$ Menu menu = mgr.createContextMenu(cursor); mgr.setRemoveAllWhenShown(true); mgr.addMenuListener(new IMenuListener() { public void menuAboutToShow(final IMenuManager manager) { LabResult lr = getSelectedResult(); if (lr != null) { LabItem li = lr.getItem(); if (!li.getTyp().equals(LabItem.typ.DOCUMENT)) { mgr.add(setStateAction); setStateAction.setChecked(lr.isFlag(LabResult.PATHOLOGIC)); } } } }); cursor.setMenu(menu); // menu.createControlContextMenu(cursor, setStateAction); rebuild(); GlobalEventDispatcher.addActivationListener(this, this); } @Override public void dispose() { GlobalEventDispatcher.removeActivationListener(this, this); super.dispose(); } public void rebuild() { actPage = 0; hDaten = new Hashtable<String, Integer>(); hGroups = new Hashtable<String, List<LabItem>>(50, 0.7f); lGroupNames = new ArrayList<String>(20); showBusy(true); createColumns(); loadItems(); createRows(); actPatient = (Patient) ElexisEventDispatcher.getSelected(Patient.class); loadValues(); showBusy(false); } LabResult actResult() { TableItem it = cursor.getRow(); int idx = cursor.getColumn(); LabItem lit = (LabItem) it.getData(KEY_ITEM); if (lit != null) { LabResult[] lrs = (LabResult[]) it.getData(KEY_VALUES); if (lrs == null) { lrs = new LabResult[NUMCOLUMNS]; it.setData(KEY_VALUES, lrs); } int column = idx - COL_OFFSET; if (column >= 0) { return lrs[idx - COL_OFFSET]; } } return null; } /* * Tabellenzelle editieren. CR oder Pfeil unten verlsst die Zelle mit Speichern und geht zur * nchst unteren Zelle. Esc verlsst die Zelle ohne speichern */ private void doEdit(final String inp) { final Text text = new Text(cursor, SWT.NONE); text.setText(inp); text.setSelection(inp.length()); text.addKeyListener(new KeyAdapter() { @Override public void keyPressed(final KeyEvent e) { if ((e.character == SWT.CR) || (e.keyCode == SWT.ARROW_DOWN)) { TableItem it = cursor.getRow(); int idx = cursor.getColumn(); // Spalte der Anzeige int idx_values = firstColumn + idx - COL_OFFSET; // Spalte // bezogen // auf // alle // Daten LabItem lit = (LabItem) it.getData(KEY_ITEM); if (lit != null) { LabResult[] lrs = (LabResult[]) it.getData(KEY_VALUES); if (lrs == null) { lrs = new LabResult[NUMCOLUMNS]; it.setData(KEY_VALUES, lrs); } LabResult lr = lrs[idx - COL_OFFSET]; TimeTool ttDaten = new TimeTool(sDaten[idx_values]); String t = text.getText(); if (lr == null) { if (t.length() > 0) { lr = new LabResult(actPatient, ttDaten, lit, text.getText(), ""); //$NON-NLS-1$ lrs[idx - COL_OFFSET] = lr; } } else { if (t.length() == 0) { lr.delete(); } else { lr.undelete(); lr.setResult(text.getText()); } } if (lr != null) { List<LabItem> toCalc = formulaRelations.get(lr.getItem().makeVarName()); if (toCalc != null) { for (LabItem litem : toCalc) { try { String evaluated = litem.evaluate(actPatient, ttDaten); if (evaluated != null) { LabResult artifact = LabResult.getForDate(actPatient, ttDaten, litem); if (artifact == null) { artifact = new LabResult(actPatient, ttDaten, litem, evaluated, ""); //$NON-NLS-1$ } else { artifact.setResult(evaluated); } Integer row = hLabItems.get(litem.getId()); if (row == null) { continue; } rows[row].setText(idx, evaluated); } } catch (ElexisException ex) { Status status = new Status(IStatus.ERROR, Hub.PLUGIN_ID, ex.getLocalizedMessage(), ex); StatusManager.getManager().handle(status, StatusManager.SHOW); } } } } } it.setText(idx, text.getText()); text.dispose(); cursorDown(); table.setFocus(); } if (e.character == SWT.DEL) { text.setText(""); //$NON-NLS-1$ } else if (e.character == SWT.ESC) { text.dispose(); table.setFocus(); } } }); editor.setEditor(text); text.setFocus(); } private void cursorDown() { int row = table.getSelectionIndex(); if (row == rows.length - 1) { return; } cursor.setSelection(row + 1, cursor.getColumn()); table.setSelection(row + 1); LabItem it = (LabItem) cursor.getRow().getData(KEY_ITEM); if (it == null) { cursorDown(); } } @Override public void setFocus() { // TODO Automatisch erstellter Methoden-Stub } public void selectionEvent(final PersistentObject obj) { if (obj instanceof Patient) { actPatient = (Patient) obj; loadValues(); } else if (obj instanceof Konsultation) { Patient p = ((Konsultation) obj).getFall().getPatient(); if ((actPatient == null) || (!p.equals(actPatient))) { actPatient = p; loadValues(); } } } private void selectPatient(Patient p) { actPatient = p; loadValues(); } /* * Daten eines neuen Patienten einlesen */ private void loadValues() { hDaten.clear(); sDaten = null; if (actPatient != null) { form.setText(actPatient.getLabel()); // Zuerst sehen, fr wieviele Daten Laborwerte vorliegen, und diese // Daten auf Index mappen // Hier mssen wir ausnahmsweise direkt auf den JdbcLink zugreifen Stm stm = PersistentObject.getConnection().getStatement(); ResultSet rs = stm.query("SELECT DISTINCT Datum FROM LABORWERTE WHERE PatientID=" //$NON-NLS-1$ + actPatient.getWrappedId() + " AND deleted='0' ORDER BY Datum"); //$NON-NLS-1$ LinkedList<String> lDaten = new LinkedList<String>(); try { int col = 0; while ((rs != null) && (rs.next() == true)) { String dat = rs.getString(1); lDaten.add(dat); hDaten.put(dat, col++); } sDaten = lDaten.toArray(new String[0]); loadPage(getLastPage()); } catch (Exception ex) { ExHandler.handle(ex); } // Referenzwerte je nach Geschlecht eintragen boolean s = (actPatient.getGeschlecht().equals("m")); //$NON-NLS-1$ for (int i = 0; i < rows.length; i++) { TableItem ti = rows[i]; LabItem li = (LabItem) ti.getData(KEY_ITEM); if (li != null) { if (s == true) { ti.setText(1, li.getRefM()); } else { ti.setText(1, li.getRefW()); } } } } else { form.setText(Messages.getString("LaborView.NoPatientSelected")); //$NON-NLS-1$ } } private int getLastPage() { return sDaten.length / NUMCOLUMNS; } /* * Eine Seite mit Laborwerten (=NUMCOLUMNS Spalten) einlesen */ private void loadPage(final int p) { // Zuerst prfen, ob die angeforderte Seite gltig ist if (p < 0) { return; } actPage = p; // Dann alte Eintrge lschen String[] line = new String[NUMCOLUMNS + COL_OFFSET]; for (int i = COL_OFFSET; i < NUMCOLUMNS + COL_OFFSET; i++) { line[i] = ""; //$NON-NLS-1$ columns[i].setText(""); //$NON-NLS-1$ } // Zeilentitel und Wertelisten vorbelegen for (int i = 0; i < rows.length; i++) { line[0] = ((String) rows[i].getData(KEY_TEXT)); rows[i].setText(line); rows[i].setData(KEY_VALUES, new LabResult[NUMCOLUMNS]); } firstColumn = (p == 0) ? 0 : (p * (NUMCOLUMNS - 1)); lastColumn = firstColumn + NUMCOLUMNS - 1; // Keine Anzeigbaren Daten vorhanden? if ((sDaten == null) || (sDaten.length == 0) || (sDaten.length < firstColumn)) { loadPage(p - 1); return; } // Query fr alle Laborwerte zwischen erstem und letztem Datum der // aktuellen Seite String sBegin = sDaten[firstColumn]; Query<LabResult> qbe = new Query<LabResult>(LabResult.class); qbe.add(LabResult.PATIENT_ID, Query.EQUALS, actPatient.getId()); qbe.add(LabResult.DATE, Query.GREATER_OR_EQUAL, sBegin); // int numvalid=NUMCOLUMNS; // Wieviele Spalten knnen tatschlich // angezeigt werden? if (lastColumn < sDaten.length) { qbe.add(LabResult.DATE, Query.LESS_OR_EQUAL, sDaten[lastColumn]); } else { lastColumn = sDaten.length - 1; } int numvalid = lastColumn - firstColumn + 1; List<LabResult> list = qbe.execute(); // Spaltenkpfe beschriften TimeTool dats = new TimeTool(); for (int i = 0; i < numvalid; i++) { String dat = sDaten[i + firstColumn]; dats.set(dat); columns[COL_OFFSET + i].setText(dats.toString(TimeTool.DATE_GER)); } // Laborresultate eintragen mithilfe der Mappings in hDaten und // hLabItems TimeTool tt = new TimeTool(); for (LabResult lr : list) { LabItem lit = lr.getItem(); if (lit == null) { log.log("Fehlerhaftes LabResult " + lr.getId(), Log.WARNINGS); //$NON-NLS-1$ continue; } tt.set(lr.getDate()); int col_values = hDaten.get(tt.toString(TimeTool.DATE_COMPACT)); // Absolute // Spalte int col_display = col_values - firstColumn + COL_OFFSET; // Spalte // relativ // zur // Seite Integer row = hLabItems.get(lit.getId()); // Zeile fr die Anzeige if (row == null) { continue; } if (LabItem.typ.DOCUMENT.equals(lit.getTyp())) { rows[row].setText(col_display, Messages.getString("LaborView.Open")); //$NON-NLS-1$ } else { rows[row].setText(col_display, lr.getResult()); // Spalte fr die } // Anzeige LabResult[] lrs = (LabResult[]) rows[row].getData(KEY_VALUES); // LabResult // anfgen if (lrs == null) { lrs = new LabResult[NUMCOLUMNS]; rows[row].setData(KEY_VALUES, lrs); } lrs[col_values - firstColumn] = lr; } } /* * Zeilen erstellen und Mappings zwischen LabItem und Zeilennummer erstellen. Jeder Gruppentitel * in blauer Farbe, darunter die Gruppe, dann eine Leerzeile. */ private void createRows() { table.removeAll(); hLabItems = new Hashtable<String, Integer>(50, 0.75f); ArrayList<TableItem> lTI = new ArrayList<TableItem>(50); int line = 0; int iteration = 0; for (String g : lGroupNames) { iteration++; List<LabItem> groupItems = hGroups.get(g); if (groupItems == null) { log.log("Fehler bei Laborgruppe " + g, Log.ERRORS); //$NON-NLS-1$ continue; } TableItem ti = new TableItem(table, SWT.NONE); ti.setForeground(Desk.getDisplay().getSystemColor(SWT.COLOR_DARK_BLUE)); // split group order token and group name Matcher m = Pattern.compile("(\\S+)\\s+(.+)").matcher(g); //$NON-NLS-1$ if (m.matches()) { String name = m.group(2); ti.setText(0, name); ti.setData(KEY_TEXT, name); } else { ti.setText("? " + g + " ?"); //$NON-NLS-1$ //$NON-NLS-2$ ti.setData(KEY_TEXT, "? " + g + " ?"); //$NON-NLS-1$ //$NON-NLS-2$ } lTI.add(ti); line += 1; for (LabItem it : groupItems) { TableItem ti2 = new TableItem(table, SWT.NONE); ti2.setData(KEY_ITEM, it); ti2.setText(it.getShortLabel()); ti2.setData(KEY_TEXT, it.getShortLabel()); lTI.add(ti2); if (it.getTyp().equals(LabItem.typ.FORMULA)) { String formel = it.getFormula(); Matcher matcher = varsPattern.matcher(formel); while (matcher.find()) { String var = matcher.group(); List<LabItem> itList = formulaRelations.get(var); if (itList == null) { itList = new ArrayList<LabItem>(); formulaRelations.put(var, itList); } itList.add(it); } } hLabItems.put(it.getId(), line++); } if (iteration < lGroupNames.size()) { TableItem tiSpace = new TableItem(table, SWT.NONE); tiSpace.setText(" "); //$NON-NLS-1$ tiSpace.setData(KEY_TEXT, " "); //$NON-NLS-1$ lTI.add(tiSpace); line += 1; } } rows = lTI.toArray(new TableItem[0]); } /** * Liste der Laboritems, Gruppiert nach groups und Sequenznummer aufbauen * */ @SuppressWarnings("unchecked") private void loadItems() { Query qbe = new Query(LabItem.class); List lItems = qbe.execute(); for (LabItem it : (List<LabItem>) lItems) { String group = it.getGroup(); List<LabItem> lGroupItems = hGroups.get(group); // Existiert die // Gruppe schon? if (lGroupItems == null) { lGroupItems = new ArrayList<LabItem>(); // Wenn nein, neu // erstellen hGroups.put(group, lGroupItems); // und in die // Groups-Hashtable einfgen int i = 0; for (i = 0; i < lGroupNames.size(); i++) { // Dann sortiert in // die Gruppenliste // eintragen. if (group.compareTo(lGroupNames.get(i)) < 0) { break; } } lGroupNames.add(i, group); } lGroupItems.add(it); // Schliesslich den Item einfgen Collections.sort(lGroupItems); // und die Itemliste neu sortieren } } public LabResult getSelectedResult() { TableItem item = cursor.getRow(); LabItem it = (LabItem) item.getData(KEY_ITEM); if (it != null) { LabResult[] lrs = (LabResult[]) item.getData(KEY_VALUES); if (lrs != null) { LabResult lr = lrs[cursor.getColumn() - COL_OFFSET]; if (lr != null) { return lr; } } } return null; } private void createColumns() { if (columns != null) { for (int i = 0; i < columns.length; i++) { columns[i].dispose(); } columns = null; } columns = new TableColumn[NUMCOLUMNS + COL_OFFSET]; for (int i = 0; i < NUMCOLUMNS + COL_OFFSET; i++) { columns[i] = new TableColumn(table, SWT.LEFT); columns[i].setWidth(75); columns[i].addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(final SelectionEvent e) { TimeTool dOld = new TimeTool(); if (dOld.set(((TableColumn) e.getSource()).getText()) == true) { DateSelectorDialog dsl = new DateSelectorDialog(getViewSite().getShell()); if (dsl.open() == Dialog.OK) { TimeTool dat = dsl.getSelectedDate(); String nDat = dat.toString(TimeTool.DATE_COMPACT); Query<LabResult> qbe = new Query<LabResult>(LabResult.class); qbe.add(LabResult.DATE, Query.EQUALS, dOld.toString(TimeTool.DATE_COMPACT)); qbe.add(LabResult.PATIENT_ID, Query.EQUALS, actPatient.getId()); for (LabResult lr : qbe.execute()) { lr.set(LabResult.DATE, nDat); } loadValues(); loadPage(actPage); } } } }); } columns[0].setWidth(200); columns[1].setWidth(70); columns[0].setText(Messages.getString("LaborView.parameter")); //$NON-NLS-1$ columns[1].setText(Messages.getString("LaborView.reference")); //$NON-NLS-1$ } private void makeActions() { fwdAction = new Action(Messages.getString("LaborView.nextPage")) { //$NON-NLS-1$ @Override public void run() { loadPage(actPage + 1); } }; backAction = new Action(Messages.getString("LaborView.prevPage")) { //$NON-NLS-1$ @Override public void run() { if (actPage > 0) { loadPage(actPage - 1); } } }; printAction = new Action(Messages.getString("LaborView.print")) { //$NON-NLS-1$ @Override public void run() { try { LaborblattView lb = (LaborblattView) getViewSite().getPage().showView(LaborblattView.ID); Patient pat = (Patient) ElexisEventDispatcher.getInstance().getSelected(Patient.class); String[] headers = new String[columns.length]; for (int i = 0; i < headers.length; i++) { headers[i] = columns[i].getText(); } lb.createLaborblatt(pat, headers, rows); } catch (Exception ex) { ExHandler.handle(ex); } } }; importAction = new Action(Messages.getString("LaborView.import")) { //$NON-NLS-1$ { setImageDescriptor(Images.IMG_IMPORT.getImageDescriptor()); setToolTipText(Messages.getString("LaborView.importToolTip")); //$NON-NLS-1$ } @Override public void run() { Importer imp = new Importer(getViewSite().getShell(), "ch.elexis.LaborDatenImport"); //$NON-NLS-1$ imp.create(); imp.setMessage(Messages.getString("LaborView.selectDataSource")); //$NON-NLS-1$ imp.getShell().setText(Messages.getString("LaborView.labImporterCaption")); //$NON-NLS-1$ imp.setTitle(Messages.getString("LaborView.labImporterText")); //$NON-NLS-1$ imp.open(); } }; xmlAction = new Action(Messages.getString("LaborView.xmlExport")) { //$NON-NLS-1$ @Override public void run() { Document doc = makeXML(); if (doc != null) { FileDialog fsel = new FileDialog( Hub.plugin.getWorkbench().getActiveWorkbenchWindow().getShell()); String fname = fsel.open(); if (fname != null) { try { FileOutputStream fout = new FileOutputStream(fname); OutputStreamWriter cout = new OutputStreamWriter(fout, "UTF-8"); //$NON-NLS-1$ XMLOutputter xout = new XMLOutputter(Format.getPrettyFormat()); xout.output(doc, cout); cout.close(); fout.close(); } catch (Exception ex) { ExHandler.handle(ex); SWTHelper.alert(Messages.getString("LaborView.ErrorCaption"), //$NON-NLS-1$ Messages.getString("LaborView.couldntwrite") + fname); //$NON-NLS-1$ } } } } }; newAction = new Action(Messages.getString("LaborView.newDate")) { //$NON-NLS-1$ @Override public void run() { DateSelectorDialog dsd = new DateSelectorDialog(getViewSite().getShell()); dsd.create(); Point m = Desk.getDisplay().getCursorLocation(); dsd.getShell().setLocation(m.x, m.y); if (dsd.open() == Dialog.OK) { if (sDaten == null) { return; } String date = dsd.getSelectedDate().toString(TimeTool.DATE_COMPACT); String[] nDates = new String[sDaten.length + 1]; System.arraycopy(sDaten, 0, nDates, 0, sDaten.length); nDates[sDaten.length] = date; hDaten.put(date, sDaten.length); sDaten = nDates; loadPage(getLastPage()); } } }; setStateAction = new Action(Messages.getString("LaborView.pathologic"), Action.AS_CHECK_BOX) { //$NON-NLS-1$ @Override public void run() { LabResult lr = getSelectedResult(); lr.setFlag(LabResult.PATHOLOGIC, isChecked()); loadPage(getLastPage()); } }; refreshAction = new Action(Messages.getString("LaborView.Refresh")) { //$NON-NLS-1$ @Override public void run() { rebuild(); } }; newAction.setImageDescriptor(Images.IMG_ADDITEM.getImageDescriptor()); // Hub.getImageDescriptor("rsc/add.gif")); fwdAction.setImageDescriptor(Images.IMG_NEXT.getImageDescriptor()); backAction.setImageDescriptor(Images.IMG_PREVIOUS.getImageDescriptor()); printAction.setImageDescriptor(Images.IMG_PRINTER.getImageDescriptor()); xmlAction.setImageDescriptor(Images.IMG_EXPORT.getImageDescriptor()); refreshAction.setImageDescriptor(Images.IMG_REFRESH.getImageDescriptor()); } public Document makeXML() { Document doc = null; try { doc = new Document(); Element r = new Element("Laborblatt"); //$NON-NLS-1$ r.setAttribute("Erstellt", new TimeTool() //$NON-NLS-1$ .toString(TimeTool.FULL_GER)); Patient actpat = (Patient) ElexisEventDispatcher.getInstance().getSelected(Patient.class); if (actpat != null) { r.setAttribute("Patient", actpat.getLabel()); //$NON-NLS-1$ } doc.setRootElement(r); Element Daten = new Element("Daten"); //$NON-NLS-1$ for (String d : sDaten) { Element dat = new Element("Datum"); //$NON-NLS-1$ dat.setAttribute("Tag", d); //$NON-NLS-1$ Daten.addContent(dat); } r.addContent(Daten); for (String g : lGroupNames) { Element eGroup = new Element("Gruppe"); //$NON-NLS-1$ eGroup.setAttribute("Name", g); //$NON-NLS-1$ List<LabItem> items = hGroups.get(g); if (items == null) { log.log("Ungltige Gruppe " + g, Log.WARNINGS); //$NON-NLS-1$ continue; } if (items.size() == 0) { continue; } for (LabItem it : items) { Element eItem = new Element("Parameter"); //$NON-NLS-1$ eItem.setAttribute("Name", it.getName()); //$NON-NLS-1$ eItem.setAttribute("Krzel", it.getKuerzel()); //$NON-NLS-1$ eItem.setAttribute("Einheit", it.getEinheit()); //$NON-NLS-1$ boolean hasContent = false; for (String t : sDaten) { Element eResult = new Element("Resultat"); //$NON-NLS-1$ eResult.setAttribute("Datum", t); //$NON-NLS-1$ eItem.addContent(eResult); List<LabResult> results = new LinkedList<LabResult>(); // hValues.get(t); for (LabResult lr : results) { if (lr.getItem().equals(it)) { eResult.addContent(lr.getResult()); hasContent = true; } } } if (hasContent == true) { Element ref = new Element("Referenz"); //$NON-NLS-1$ ref.setAttribute(Person.MALE, it.get("RefMann")); //$NON-NLS-1$ //$NON-NLS-2$ ref.setAttribute(Person.FEMALE, it.get("RefFrauOrTx")); //$NON-NLS-1$ //$NON-NLS-2$ eItem.addContent(ref); eGroup.addContent(eItem); } } if (eGroup.getContentSize() != 0) { r.addContent(eGroup); } } } catch (Exception ex) { ExHandler.handle(ex); } return doc; } public void visible(final boolean mode) { if (mode == true) { ElexisEventDispatcher.getInstance().addListeners(eeli_labitem, eeli_pat); Patient act = (Patient) ElexisEventDispatcher.getSelected(Patient.class); if ((act != null) && ((actPatient == null) || (!act.getId().equals(actPatient.getId())))) { actPatient = act; loadValues(); } } else { ElexisEventDispatcher.getInstance().removeListeners(eeli_labitem, eeli_pat); } } public void activation(final boolean mode) { } /*********************************************************************************************** * Die folgenden 6 Methoden implementieren das Interface ISaveablePart2 Wir bentigen das * Interface nur, um das Schliessen einer View zu verhindern, wenn die Perspektive fixiert ist. * Gibt es da keine einfachere Methode? */ public int promptToSaveOnClose() { return GlobalActions.fixLayoutAction.isChecked() ? ISaveablePart2.CANCEL : ISaveablePart2.NO; } public void doSave(final IProgressMonitor monitor) { /* leer */ } public void doSaveAs() { /* leer */ } public boolean isDirty() { return true; } public boolean isSaveAsAllowed() { return false; } public boolean isSaveOnCloseNeeded() { return true; } public void reloadContents(final Class clazz) { if (clazz.equals(LabItem.class)) { } } }