/******************************************************************************* * Copyright (c) 2012-2015 INRIA. * 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: * Generoso Pagano - initial API and implementation ******************************************************************************/ package fr.inria.soctrace.framesoc.ui.dialogs; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; import java.util.regex.PatternSyntaxException; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.layout.TableColumnLayout; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.OwnerDrawLabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.jface.viewers.ViewerSorter; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.ColorDialog; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; import org.eclipse.wb.swt.ResourceManager; import fr.inria.soctrace.framesoc.ui.Activator; import fr.inria.soctrace.framesoc.ui.colors.FramesocColor; import fr.inria.soctrace.framesoc.ui.colors.FramesocColorManager; import fr.inria.soctrace.lib.model.utils.ModelConstants.ModelEntity; /** * Dialog to manage Framesoc colors. * * @author "Generoso Pagano <generoso.pagano@inria.fr>" */ public class ManageColorsComposite extends Composite { /** * Model entity combo */ private Combo comboModelEntity; /** * Filter text */ private Text textFilter; /** * The viewer */ private TableViewer tableViewer; /** * Entity managed */ private ModelEntity entity; /** * Edit button */ private Button btnEdit; /** * Reset button */ protected Button btnReset; private Dialog parentDialog; /** * Color images */ protected Map<String, Image> images; /** * Collection to save the temporary color changes */ protected Map<ModelEntity, Map<String, FramesocColor>> modifiedColors; protected class Entity { String name; ModelEntity entity; public Entity(String name, ModelEntity entity) { this.name = name; this.entity = entity; } } protected Map<Integer, Entity> entities; protected final static String ET_NAME = "Event Types"; protected final static String EP_NAME = "Event Producers"; /** * Constructor * * @param parentShell * shell */ public ManageColorsComposite(Composite parentComposite, Dialog parentDialog) { super(parentComposite, SWT.NONE); this.parentDialog = parentDialog; this.images = new HashMap<String, Image>(); this.entities = new TreeMap<Integer, Entity>(); this.entities.put(0, new Entity(EP_NAME, ModelEntity.EVENT_PRODUCER)); this.entities.put(1, new Entity(ET_NAME, ModelEntity.EVENT_TYPE)); modifiedColors = new HashMap<ModelEntity, Map<String, FramesocColor>>(); } protected void createPartControl() { Composite all = this; comboModelEntity = new Combo(all, SWT.READ_ONLY); comboModelEntity.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); Iterator<Entry<Integer, Entity>> it = entities.entrySet().iterator(); while (it.hasNext()) { Entry<Integer, Entity> e = it.next(); comboModelEntity.add(e.getValue().name, e.getKey()); comboModelEntity.select(e.getKey()); // select the last entity = e.getValue().entity; modifiedColors.put(entity, new HashMap<String, FramesocColor>()); } comboModelEntity.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { entity = entities.get(comboModelEntity.getSelectionIndex()).entity; textFilter.setText(""); tableViewer.setInput(getNames()); tableViewer.setSelection(null); tableViewer.refresh(true); } }); textFilter = new Text(all, SWT.BORDER); textFilter.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { tableViewer.refresh(); } }); textFilter.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); Composite composite = new Composite(all, SWT.NONE); GridLayout gl_composite = new GridLayout(2, false); gl_composite.verticalSpacing = 0; gl_composite.marginWidth = 0; gl_composite.marginHeight = 0; composite.setLayout(gl_composite); composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); Composite names = new Composite(composite, SWT.NONE); TableColumnLayout tableColumnLayout = new TableColumnLayout(); names.setLayout(tableColumnLayout); names.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); // list tableViewer = new TableViewer(names, SWT.BORDER | SWT.V_SCROLL | SWT.SINGLE); Table table = tableViewer.getTable(); GridData gd_table = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1); gd_table.widthHint = 422; table.setLayoutData(gd_table); tableViewer .addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { IStructuredSelection selection = (IStructuredSelection) tableViewer .getSelection(); if (selection.size() <= 0) { btnEdit.setEnabled(false); } if (selection.size() == 1) { btnEdit.setEnabled(true); } else { btnEdit.setEnabled(false); } } }); TableViewerColumn nameColumn = new TableViewerColumn(tableViewer, SWT.NONE); nameColumn.setLabelProvider(new RowLabelProvider()); tableViewer.setContentProvider(ArrayContentProvider.getInstance()); tableViewer.setSorter(new ViewerSorter()); tableViewer.addFilter(new RowFilter()); tableViewer.setInput(getNames()); // Windows fix: Set column width to the full width of the table tableColumnLayout.setColumnData(nameColumn.getColumn(), new ColumnWeightData(100, false)); // buttons Composite compositeButtons = new Composite(composite, SWT.NONE); compositeButtons.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true, 1, 1)); compositeButtons.setLayout(new GridLayout(1, false)); compositeButtons.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1)); btnEdit = new Button(compositeButtons, SWT.NONE); btnEdit.setEnabled(false); btnEdit.setToolTipText("Edit Color"); btnEdit.setImage(ResourceManager.getPluginImage( "fr.inria.soctrace.framesoc.ui", "icons/edit2.png")); btnEdit.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { IStructuredSelection selection = (IStructuredSelection) tableViewer .getSelection(); Iterator<?> it = selection.iterator(); // Should be only one name in the selection (multiple selection // not allowed) while (it.hasNext()) { String name = (String) it.next(); ColorDialog dialog = new ColorDialog(parentDialog .getShell()); FramesocColor c; // If color was already modified if (modifiedColors.get(entity).containsKey(name)) c = modifiedColors.get(entity).get(name); else c = getColor(name); dialog.setRGB(new RGB(c.red, c.green, c.blue)); RGB rgb = dialog.open(); if (rgb == null) continue; modifiedColors.get(entity).put(name, new FramesocColor(rgb.red, rgb.green, rgb.blue)); disposeImages(); btnReset.setEnabled(true); tableViewer.refresh(true); } } }); btnReset = new Button(compositeButtons, SWT.NONE); btnReset.setEnabled(false); btnReset.setToolTipText("Reload from Configuration File"); btnReset.setImage(ResourceManager.getPluginImage(Activator.PLUGIN_ID, "icons/load.png")); btnReset.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { modifiedColors.get(entity).clear(); disposeImages(); btnReset.setEnabled(false); tableViewer.refresh(true); } }); } public void disposeImages() { for (Image img : images.values()) { img.dispose(); } images.clear(); } protected FramesocColor getColor(String name) { if (entity.equals(ModelEntity.EVENT_TYPE)) return FramesocColorManager.getInstance().getEventTypeColor(name); else return FramesocColorManager.getInstance().getEventProducerColor( name); } private void setColor(String name, FramesocColor color, ModelEntity anEntity) { if (anEntity.equals(ModelEntity.EVENT_TYPE)) FramesocColorManager.getInstance().setEventTypeColor(name, color); else FramesocColorManager.getInstance().setEventProducerColor(name, color); } /** * Save the colors in the external color configuration file * * @return true if there was at least one modification, false otherwise */ public boolean saveColors() { boolean hasChanged = saveModifiedColors(); if (hasChanged) { FramesocColorManager.getInstance().saveEventTypeColors(); FramesocColorManager.getInstance().saveEventProducerColors(); } return hasChanged; } /** * Save the modifications in memory * * @return true if there was at least one modification, false otherwise */ private boolean saveModifiedColors() { boolean hasChanged = false; for (ModelEntity modelEntity : modifiedColors.keySet()) { for (String name : modifiedColors.get(modelEntity).keySet()) { setColor(name, modifiedColors.get(modelEntity).get(name), modelEntity); hasChanged = true; } } return hasChanged; } protected Collection<String> getNames() { if (entity.equals(ModelEntity.EVENT_TYPE)) return FramesocColorManager.getInstance().getEventTypeNames(); else return FramesocColorManager.getInstance().getEventProducerNames(); } public ModelEntity getEntity() { return entity; } public void setEntity(ModelEntity entity) { this.entity = entity; } public class RowFilter extends ViewerFilter { @Override public boolean select(Viewer viewer, Object parentElement, Object element) { String row = (String) element; if (textFilter.getText().equals("")) return true; try { if (row.matches(".*" + textFilter.getText() + ".*")) { return true; } } catch (PatternSyntaxException e) { MessageDialog.openError(Display.getDefault().getActiveShell(), "Wrong search string", "The expression used as search string is not valid: " + textFilter.getText()); textFilter.setText(""); } return false; } } public class RowLabelProvider extends OwnerDrawLabelProvider { @Override protected void paint(Event event, Object element) { String name = (String) element; Rectangle bounds = ((TableItem) event.item).getBounds(event.index); Image img = null; if (images.containsKey(name)) { img = images.get(name); } else { img = new Image(event.display, bounds.height / 2, bounds.height / 2); GC gc = new GC(img); Color border = new Color(event.display, 0, 0, 0); gc.setBackground(border); gc.fillRectangle(0, 0, bounds.height / 2, bounds.height / 2); // If the color was previously modified if (modifiedColors.get(entity).containsKey(name)) { // Use the modified color gc.setBackground(modifiedColors.get(entity).get(name) .getSwtColor()); } else { gc.setBackground(getColor(name).getSwtColor()); } gc.fillRectangle(1, 1, bounds.height / 2 - 2, bounds.height / 2 - 2); gc.dispose(); border.dispose(); images.put(name, img); } // center image and text on y bounds.height = bounds.height / 2 - img.getBounds().height / 2; int imgy = bounds.height > 0 ? bounds.y + bounds.height : bounds.y; int texty = bounds.y + 3; event.gc.drawText(name, bounds.x + img.getBounds().width + 5, texty, true); event.gc.drawImage(img, bounds.x, imgy); } @Override protected void measure(Event event, Object element) { // nothing to do } } }