/******************************************************************************************** * Copyright (c) 2015, 2016 itemis AG and others. * * 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: * Tamas Miklossy (itemis AG) - Exporting *.dot files in different formats (bug #446647) * *********************************************************************************************/ package org.eclipse.gef.dot.internal.ui; import org.eclipse.core.runtime.Assert; import org.eclipse.jface.preference.RadioGroupFieldEditor; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; public class DotExportRadioGroupFieldEditor extends RadioGroupFieldEditor { /** * List of radio button entries of the form [label,value]. */ private String[][] labelsAndValues; /** * Number of columns into which to arrange the radio buttons. */ private int numColumns; /** * Indent used for the first column of the radio button matrix. */ private int indent = HORIZONTAL_GAP; /** * The current value, or <code>null</code> if none. */ private String value; /** * The box of radio buttons, or <code>null</code> if none (before creation * and after disposal). */ private Composite radioBox; /** * The radio buttons, or <code>null</code> if none (before creation and * after disposal). */ private Button[] radioButtons; /** * Whether to use a Group control. */ private boolean useGroup; /** * Parent Composite of the fieldEditor */ private Composite parent; private Label dotExportHintLabel; private String dotExportHintText; /** * Creates a new radio group field editor */ protected DotExportRadioGroupFieldEditor() { } public DotExportRadioGroupFieldEditor(String name, String labelText, String dotExportHintText, int numColumns, String[][] labelsAndValues, Composite parent) { this(name, labelText, dotExportHintText, numColumns, labelsAndValues, parent, false); } public DotExportRadioGroupFieldEditor(String name, String labelText, String dotExportHintText, int numColumns, String[][] labelsAndValues, Composite parent, boolean useGroup) { init(name, labelText); if (labelsAndValues != null) { Assert.isTrue(checkArray(labelsAndValues)); } this.labelsAndValues = labelsAndValues; this.numColumns = numColumns; this.useGroup = useGroup; this.parent = parent; this.dotExportHintText = dotExportHintText; createControl(parent); } @Override protected void adjustForNumColumns(int numColumns) { Control control = getLabelControl(); if (control != null) { ((GridData) control.getLayoutData()).horizontalSpan = numColumns; } ((GridData) radioBox.getLayoutData()).horizontalSpan = numColumns; } private boolean checkArray(String[][] table) { if (table == null) { return false; } for (int i = 0; i < table.length; i++) { String[] array = table[i]; if (array == null || array.length != 2) { return false; } } return true; } @Override protected void doFillIntoGrid(Composite parent, int numColumns) { if (useGroup) { Control control = getRadioBoxControl(parent); GridData gd = new GridData(GridData.FILL_HORIZONTAL); control.setLayoutData(gd); } else { Control control = getLabelControl(parent); GridData gd = new GridData(); gd.horizontalSpan = numColumns; control.setLayoutData(gd); control = getRadioBoxControl(parent); gd = new GridData(); gd.horizontalSpan = numColumns; gd.horizontalIndent = indent; control.setLayoutData(gd); } } @Override protected void doLoad() { updateValue(getPreferenceStore().getString(getPreferenceName())); } @Override protected void doLoadDefault() { // do nothing, since the DotExportRadioGroupFieldEditor has no default // value } @Override protected void doStore() { if (value == null) { getPreferenceStore().setToDefault(getPreferenceName()); return; } getPreferenceStore().setValue(getPreferenceName(), value); } @Override public Composite getRadioBoxControl(Composite parent) { if (radioBox == null) { Font font = parent.getFont(); if (useGroup) { Group group = new Group(parent, SWT.NONE); group.setFont(font); String text = getLabelText(); if (text != null) { group.setText(text); } radioBox = group; GridLayout layout = new GridLayout(); layout.horizontalSpacing = HORIZONTAL_GAP; layout.numColumns = numColumns; radioBox.setLayout(layout); } else { radioBox = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(); layout.marginWidth = 0; layout.marginHeight = 0; layout.horizontalSpacing = HORIZONTAL_GAP; layout.numColumns = numColumns; radioBox.setLayout(layout); radioBox.setFont(font); } dotExportHintLabel = new Label(parent, SWT.NONE); dotExportHintLabel.setText(dotExportHintText); FontData fontData = dotExportHintLabel.getFont().getFontData()[0]; Font boldFont = new Font(Display.getCurrent(), new FontData( fontData.getName(), fontData.getHeight() - 1, SWT.BOLD)); dotExportHintLabel.setFont(boldFont); GridData gridData = new GridData(); gridData.horizontalSpan = 2; dotExportHintLabel.setLayoutData(gridData); if (labelsAndValues != null) { radioButtons = new Button[labelsAndValues.length]; for (int i = 0; i < labelsAndValues.length; i++) { Button radio = new Button(radioBox, SWT.RADIO | SWT.LEFT); radioButtons[i] = radio; String[] labelAndValue = labelsAndValues[i]; radio.setText(labelAndValue[0]); radio.setData(labelAndValue[1]); radio.setFont(font); radio.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { String oldValue = value; value = (String) event.widget.getData(); setPresentsDefaultValue(false); fireValueChanged(VALUE, oldValue, value); } }); } hideDotExportHintLabel(); } radioBox.addDisposeListener(new DisposeListener() { @Override public void widgetDisposed(DisposeEvent event) { radioBox = null; radioButtons = null; } }); } else { checkParent(radioBox, parent); } return radioBox; } @Override public void setIndent(int indent) { if (indent < 0) { this.indent = 0; } else { this.indent = indent; } } private void updateValue(String selectedValue) { this.value = selectedValue; if (radioButtons == null) { return; } if (this.value != null) { boolean found = false; for (int i = 0; i < radioButtons.length; i++) { Button radio = radioButtons[i]; boolean selection = false; if (((String) radio.getData()).equals(this.value)) { selection = true; found = true; } radio.setSelection(selection); } if (found) { return; } } // We weren't able to find the value. So we select the first // radio button as a default. if (radioButtons.length > 0) { radioButtons[0].setSelection(true); this.value = (String) radioButtons[0].getData(); } return; } @Override public void setEnabled(boolean enabled, Composite parent) { if (!useGroup) { super.setEnabled(enabled, parent); } for (int i = 0; i < radioButtons.length; i++) { radioButtons[i].setEnabled(enabled); } } public void update(final String[][] newLabelsAndValues) { Display.getDefault().syncExec(new Runnable() { @Override public void run() { clear(); labelsAndValues = newLabelsAndValues; if (radioBox == null) { if (parent.isDisposed()) { return; } if (useGroup) { Group group = new Group(parent, SWT.NONE); String text = getLabelText(); if (text != null) { group.setText(text); } radioBox = group; GridLayout layout = new GridLayout(); layout.horizontalSpacing = HORIZONTAL_GAP; layout.numColumns = numColumns; radioBox.setLayout(layout); } else { radioBox = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(); layout.marginWidth = 0; layout.marginHeight = 0; layout.horizontalSpacing = HORIZONTAL_GAP; layout.numColumns = numColumns; radioBox.setLayout(layout); } } if (labelsAndValues != null) { radioButtons = new Button[labelsAndValues.length]; for (int i = 0; i < labelsAndValues.length; i++) { Button radio = new Button(radioBox, SWT.RADIO | SWT.LEFT); radioButtons[i] = radio; String[] labelAndValue = labelsAndValues[i]; radio.setText(labelAndValue[0]); radio.setData(labelAndValue[1]); radio.setFont(parent.getFont()); radio.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { String oldValue = value; value = (String) event.widget.getData(); setPresentsDefaultValue(false); fireValueChanged(VALUE, oldValue, value); } }); } load(); hideDotExportHintLabel(); parent.layout(); } } }); } protected void hideDotExportHintLabel() { // hide the dot export hint label dotExportHintLabel.setVisible(false); ((GridData) dotExportHintLabel.getLayoutData()).exclude = true; } protected void showHideDotExportHintLabel() { // show the dot export hint label dotExportHintLabel.setVisible(true); ((GridData) dotExportHintLabel.getLayoutData()).exclude = false; } public void clear() { this.labelsAndValues = null; if (radioButtons != null) { for (Button radioButton : radioButtons) { radioButton.dispose(); } showHideDotExportHintLabel(); // do synchronous layout Display.getDefault().syncExec(new Runnable() { @Override public void run() { parent.layout(); } }); } } }