/******************************************************************************* * Copyright (c) 2006-2010, G. Weirich and Elexis * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * G. Weirich - initial implementation * *******************************************************************************/ package ch.elexis.base.ch.diagnosecodes.views; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import ch.elexis.core.ui.util.viewers.CommonViewer; import ch.elexis.core.ui.util.viewers.DefaultControlFieldProvider; import ch.elexis.core.ui.util.viewers.SimpleWidgetProvider; import ch.elexis.core.ui.util.viewers.ViewerConfigurer; import ch.elexis.core.ui.util.viewers.ViewerConfigurer.ICommonViewerContentProvider; import ch.elexis.core.ui.views.codesystems.CodeSelectorFactory; import ch.elexis.data.TICode; public class TICodeSelectorFactory extends CodeSelectorFactory { public TICodeSelectorFactory(){} @Override public ViewerConfigurer createViewerConfigurer(CommonViewer cv){ return new ViewerConfigurer(new TICodeContentProvider(cv), new TICodeLabelProvider(), new DefaultControlFieldProvider(cv, new String[] { "Text"}), //$NON-NLS-1$ new ViewerConfigurer.DefaultButtonProvider(), new SimpleWidgetProvider( SimpleWidgetProvider.TYPE_TREE, SWT.NONE, null)); } static class TICodeContentProvider implements ITreeContentProvider, ICommonViewerContentProvider { private CommonViewer viewer; private String value; private String TICKey = "Text"; private List<TICode> nodes; private List<TICode> childs; private List<TICode> allNodes; public TICodeContentProvider(CommonViewer viewer){ this.viewer = viewer; allNodes = new ArrayList<TICode>(Arrays.asList(TICode.getRootNodes())); nodes = allNodes; value = ""; } public Object[] getChildren(Object parentElement){ TICode c = (TICode) parentElement; // get all children if no search value is set if (value == null || value.isEmpty()) { return c.getChildren(); } // only show children that match the search query List<TICode> availableChildren = new ArrayList<TICode>(); for (TICode tic : c.getChildren()) { if (childs.contains(tic)) { availableChildren.add(tic); } } return availableChildren.toArray(new TICode[availableChildren.size()]); } public Object getParent(Object element){ TICode c = (TICode) element; return c.getParent(); } public boolean hasChildren(Object element){ TICode c = (TICode) element; return c.hasChildren(); } public Object[] getElements(Object inputElement){ return nodes.toArray(new TICode[nodes.size()]); } public void dispose(){ // TODO Auto-generated method stub } public void inputChanged(Viewer v, Object oldInput, Object newInput){} public void startListening(){ viewer.getConfigurer().getControlFieldProvider().addChangeListener(this); } public void stopListening(){ viewer.getConfigurer().getControlFieldProvider().removeChangeListener(this); } public void changed(HashMap<String, String> values){ String filterText = values.get(TICKey).toLowerCase(); if (filterText == null || filterText.isEmpty() || filterText.equals("%")) { nodes = allNodes; setFilterValue(""); } else { List<TICode> filteredTICodes = new ArrayList<TICode>(); boolean startMatchesOnly = true; // search for any match if query starts with % if (filterText.startsWith("%")) { filterText = filterText.replace("%", ""); startMatchesOnly = false; } setFilterValue(filterText); filteredTICodes = findMatchingTiCodes(filterText, startMatchesOnly); nodes = filteredTICodes; } // update view viewer.notify(CommonViewer.Message.update); } /** * looks for TICode texts that match with the searched query * * @param search * pattern * @param startMatchesOnly * whether only to search for {@link TICode}s starting with the pattern ( * {@code true} or containing it anywhere in the name ({@code false}) * @return list of search term matching TICodes */ private List<TICode> findMatchingTiCodes(String search, boolean startMatchesOnly){ childs = new ArrayList<TICode>(); List<TICode> matches = new ArrayList<TICode>(); for (TICode tiCode : allNodes) { String text = tiCode.getText().toLowerCase(); if (isMatch(search, text, startMatchesOnly)) { matches.add(tiCode); } matches = addMatchingChildren(search, startMatchesOnly, matches, tiCode.getChildren(), tiCode); } return matches; } /** * adds all children who's names match the search pattern * * @param search * word/pattern * @param startMatchesOnly * {@link TICode} must {@code true}: start with pattern/ {@code false}: contain * pattern * @param matches * list of matching parents * @param tiChildren * all relevant children * @param parent * @return up to date list of matching parents */ private List<TICode> addMatchingChildren(String search, boolean startMatchesOnly, List<TICode> matches, TICode[] tiChildren, TICode parent){ for (TICode tic : tiChildren) { String text = tic.getText().toLowerCase(); if (isMatch(search, text, startMatchesOnly)) { childs.add(tic); if (!matches.contains(parent)) { matches.add(parent); } } } return matches; } private boolean isMatch(String search, String text, boolean startMatchesOnly){ if (startMatchesOnly) { return text.startsWith(search); } else { return text.contains(search); } } public void reorder(String field){} public void selected(){} @Override public void init(){ // TODO Auto-generated method stub } private void setFilterValue(String value){ this.value = value; } } static class TICodeLabelProvider extends LabelProvider { public String getText(Object element){ TICode c = (TICode) element; return c.getCode() + " " + c.getText(); //$NON-NLS-1$ } @Override public Image getImage(Object element){ return null; } } @Override public Class getElementClass(){ return TICode.class; } @Override public void dispose(){} @Override public String getCodeSystemName(){ return "TI-Code"; //$NON-NLS-1$ } }