| /******************************************************************************* |
| * Copyright (c) 2011 University of Illinois 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: |
| * Albert L. Rossi - design and implementation |
| ******************************************************************************/ |
| package org.eclipse.ptp.rm.jaxb.ui.model; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.jface.viewers.CheckStateChangedEvent; |
| import org.eclipse.jface.viewers.ColumnViewer; |
| import org.eclipse.jface.viewers.DoubleClickEvent; |
| import org.eclipse.jface.viewers.ICheckStateListener; |
| import org.eclipse.jface.viewers.ICheckable; |
| import org.eclipse.jface.viewers.IDoubleClickListener; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.jface.viewers.ViewerFilter; |
| import org.eclipse.ptp.rm.jaxb.core.data.TemplateType; |
| import org.eclipse.ptp.rm.jaxb.ui.ICellEditorUpdateModel; |
| import org.eclipse.ptp.rm.jaxb.ui.JAXBUIPlugin; |
| import org.eclipse.ptp.rm.jaxb.ui.handlers.ValueUpdateHandler; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.events.SelectionListener; |
| import org.eclipse.swt.widgets.Button; |
| |
| /** |
| * Update model for the entire viewer (CheckboxTable or CheckboxTree). <br> |
| * <br> |
| * The viewer needs to be acted on as a whole on updates when check state |
| * changes, and it needs to be refreshed after updates. |
| * |
| * @author arossi |
| * |
| */ |
| public class ViewerUpdateModel extends AbstractUpdateModel implements ICheckStateListener, IDoubleClickListener, SelectionListener { |
| private final StringBuffer checked; |
| private final StringBuffer templatedValue; |
| private final String pattern; |
| private final String separator; |
| private final ICheckable viewer; |
| private final ColumnViewer columnViewer; |
| private Button showOnlySelected; |
| |
| /** |
| * Used to filter out unchecked items. |
| */ |
| private final ViewerFilter filter = new ViewerFilter() { |
| @Override |
| public boolean select(Viewer viewer, Object parentElement, Object element) { |
| if (element instanceof ICellEditorUpdateModel) { |
| return ((ICheckable) viewer).getChecked(element); |
| } else if (element instanceof InfoTreeNodeModel) { |
| Object parent = ((InfoTreeNodeModel) element).getParent(); |
| return ((ICheckable) viewer).getChecked(parent); |
| } |
| return false; |
| } |
| }; |
| |
| /** |
| * @param name |
| * An arbitrary name given to the viewer; the viewer string |
| * output (produced from the pattern template) will be stored in |
| * the environment as the value of this name, and thus can be |
| * referenced by other widget models. |
| * @param handler |
| * the handler for notifying other widgets to refresh their |
| * values |
| * @param viewer |
| * the checkable viewer the object models |
| * @param template |
| * JAXB data element defining a pattern by which to process the |
| * name-value pairs associated with the items of the viewer into |
| * a single output string |
| */ |
| public ViewerUpdateModel(String name, ValueUpdateHandler handler, ICheckable viewer, TemplateType template) { |
| super(name, handler); |
| this.viewer = viewer; |
| this.columnViewer = (ColumnViewer) viewer; |
| pattern = template.getPattern(); |
| String s = template.getSeparator(); |
| separator = s == null ? ZEROSTR : s; |
| checked = new StringBuffer(); |
| templatedValue = new StringBuffer(); |
| viewer.addCheckStateListener(this); |
| columnViewer.addDoubleClickListener(this); |
| } |
| |
| /* |
| * Model serves as CheckStateListener for the viewer. When check state |
| * changes, the checked values are stored, and the update handler notified. |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse |
| * .jface.viewers.CheckStateChangedEvent) |
| */ |
| public void checkStateChanged(CheckStateChangedEvent event) { |
| Object target = event.getElement(); |
| if (!(target instanceof ICellEditorUpdateModel)) { |
| viewer.setChecked(target, false); |
| } |
| storeValue(); |
| handleUpdate(null); |
| } |
| |
| /* |
| * Model serves as DoubleClickListener for the viewer. Multiple rows can be |
| * selected, and their checked state toggled using a double-click. Each |
| * toggle generates a CheckStateChangedEvent passed directly to the {@link |
| * #checkStateChanged(CheckStateChangedEvent)} method.(non-Javadoc) |
| * |
| * @see |
| * org.eclipse.jface.viewers.IDoubleClickListener#doubleClick(org.eclipse |
| * .jface.viewers.DoubleClickEvent) |
| */ |
| public void doubleClick(DoubleClickEvent event) { |
| List<CheckStateChangedEvent> csEvents = new ArrayList<CheckStateChangedEvent>(); |
| try { |
| IStructuredSelection selection = (IStructuredSelection) ((ColumnViewer) viewer).getSelection(); |
| List<?> selected = selection.toList(); |
| if (!selected.isEmpty()) { |
| for (Object o : selected) { |
| boolean checked = viewer.getChecked(o); |
| if (o instanceof ICellEditorUpdateModel) { |
| ICellEditorUpdateModel model = (ICellEditorUpdateModel) o; |
| viewer.setChecked(model, !checked); |
| } else { |
| viewer.setChecked(o, false); |
| } |
| csEvents.add(new CheckStateChangedEvent(viewer, o, !checked)); |
| } |
| } |
| } catch (Throwable t) { |
| JAXBUIPlugin.log(t); |
| } |
| for (CheckStateChangedEvent e : csEvents) { |
| checkStateChanged(e); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.ui.model.AbstractUpdateModel#getControl() |
| */ |
| @Override |
| public Object getControl() { |
| return viewer; |
| } |
| |
| /* |
| * Returns the mapValue in this case, since there is not actually a single |
| * value associated with the viewer. (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.ui.IUpdateModel#getValueFromControl() |
| */ |
| public Object getValueFromControl() { |
| return mapValue; |
| } |
| |
| /** |
| * Set up the initial state of the viewer from the initial state of the |
| * items; set the button state controlling the filter from the initial map |
| * value. |
| * |
| * @throws CoreException |
| */ |
| @SuppressWarnings("unchecked") |
| public void initializeChecked() throws CoreException { |
| Map<String, String> allChecked = lcMap.getChecked(name); |
| Collection<Object> input = (Collection<Object>) ((Viewer) viewer).getInput(); |
| for (Object o : input) { |
| boolean checked = false; |
| if (o instanceof ICellEditorUpdateModel) { |
| ICellEditorUpdateModel model = (ICellEditorUpdateModel) o; |
| if (allChecked.isEmpty()) { |
| checked = true; |
| } else { |
| checked = allChecked.containsKey(model.getName()); |
| } |
| viewer.setChecked(model, checked); |
| } else { |
| viewer.setChecked(o, false); |
| } |
| } |
| |
| Boolean b = (Boolean) lcMap.get(SHOW_ONLY_CHECKED + name); |
| if (b == null) { |
| b = false; |
| } |
| showOnlySelected.setSelection(b); |
| if (b) { |
| columnViewer.addFilter(filter); |
| } |
| storeValue(); |
| handleUpdate(null); |
| } |
| |
| /* |
| * Store the checked string and the show-only-checked setting (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.ui.model.AbstractUpdateModel#storeValue() |
| */ |
| @SuppressWarnings("unchecked") |
| public void putCheckedSettings(Map<String, Object> localMap) { |
| checked.setLength(0); |
| Collection<Object> input = (Collection<Object>) ((Viewer) viewer).getInput(); |
| for (Object o : input) { |
| if (o instanceof ICellEditorUpdateModel) { |
| ICellEditorUpdateModel model = (ICellEditorUpdateModel) o; |
| if (model.isChecked()) { |
| checked.append(model.getName()).append(SP); |
| } |
| } |
| } |
| localMap.put(CHECKED_ATTRIBUTES + name, checked.toString().trim()); |
| localMap.put(SHOW_ONLY_CHECKED + name, showOnlySelected.getSelection()); |
| } |
| |
| /* |
| * Retrieves the last value of the pattern string.(non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.ui.IUpdateModel#refreshValueFromMap() |
| */ |
| public void refreshValueFromMap() { |
| mapValue = lcMap.get(name); |
| } |
| |
| /** |
| * @param showOnlySelected |
| * whether to apply filter to viewer |
| */ |
| public void setShowAll(Button showOnlySelected) { |
| this.showOnlySelected = showOnlySelected; |
| } |
| |
| /* |
| * Store the template setting (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.jaxb.ui.model.AbstractUpdateModel#storeValue() |
| */ |
| @SuppressWarnings("unchecked") |
| @Override |
| public void storeValue() { |
| templatedValue.setLength(0); |
| Collection<Object> input = (Collection<Object>) ((Viewer) viewer).getInput(); |
| for (Object o : input) { |
| if (o instanceof ICellEditorUpdateModel) { |
| ICellEditorUpdateModel model = (ICellEditorUpdateModel) o; |
| /* |
| * model will return ZEROSTR if the entry is not selected |
| */ |
| String replaced = model.getReplacedValue(pattern); |
| if (!ZEROSTR.equals(replaced)) { |
| templatedValue.append(separator).append(replaced); |
| } |
| } |
| } |
| templatedValue.delete(0, separator.length()); |
| String t = templatedValue.toString().trim(); |
| if (!ZEROSTR.equals(t)) { |
| lcMap.put(name, t); |
| } else { |
| lcMap.remove(name); |
| } |
| } |
| |
| /* |
| * Model serves as widget selected listener for the filter button. |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse |
| * .swt.events.SelectionEvent) |
| */ |
| public void widgetDefaultSelected(SelectionEvent e) { |
| widgetSelected(e); |
| } |
| |
| /* |
| * Model serves as widget selected listener for the filter button. |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt |
| * .events.SelectionEvent) |
| */ |
| public void widgetSelected(SelectionEvent e) { |
| if (showOnlySelected.getSelection()) { |
| columnViewer.addFilter(filter); |
| } else { |
| columnViewer.removeFilter(filter); |
| } |
| } |
| } |