/** * Copyright 2014 SAP AG * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spotter.eclipse.ui.editors; import java.text.MessageFormat; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.DirectoryDialog; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.lpe.common.config.ConfigParameterDescription; import org.spotter.eclipse.ui.dialogs.ConfigParamSetEditingDialog; /** * A custom dialog cell editor used by <code>PropertiesEditingSupport</code>. No * SWT control is used by this editor to open the dialog, editing starts * directly when the cell editor gets activated. * * @author Denis Knoepfle * */ public class CustomDialogCellEditor extends CellEditor { /** * The corresponding configuration parameter description. */ private ConfigParameterDescription configParamDesc; private Composite editorComposite; private Label editorLabel; /** * The value of this cell editor; initially <code>null</code>. */ private Object value = null; /** * Creates a new dialog parented under the given control. * * @param parent * the parent control */ public CustomDialogCellEditor(Composite parent) { super(parent); } /** * Sets the corresponding configuration parameter description. * * @param configParamDesc * The configuration parameter description. */ public void setConfigParameterDescription(ConfigParameterDescription configParamDesc) { this.configParamDesc = configParamDesc; } /** * This will directly start editing the cell. Needs to be executed as * asynchronous <code>Runnable</code> because of the structure of the * framework and because <code>activate()</code> must return first before * <code>editValue()</code> can be called. */ @Override public void activate() { Display.getDefault().asyncExec(new Runnable() { @Override public void run() { editValue(); } }); } /** * Creates the label used to show the value of this cell editor. * * @param cell * the control for this cell editor * @return the newly created label */ protected Control createContents(Composite cell) { editorLabel = new Label(cell, SWT.LEFT); editorLabel.setBackground(cell.getBackground()); editorLabel.setFont(cell.getFont()); return editorLabel; } /** * Creates a composite which serves as this cell editor's control. * * @param parent * the parent composite * @return the new control */ protected Control createControl(Composite parent) { Color bgColor = parent.getBackground(); Font font = parent.getFont(); editorComposite = new Composite(parent, getStyle()); editorComposite.setBackground(bgColor); editorComposite.setFont(font); editorComposite.setLayout(new FillLayout()); createContents(editorComposite); setValueValid(true); updateLabel(value); return editorComposite; } /** * Returns the value of this cell editor. * * @return the value of this cell editor */ @Override protected Object doGetValue() { return value; } /** * Sets the value of this cell editor and updates the label. * * @param value * the value of this cell editor */ protected void doSetValue(Object value) { this.value = value; updateLabel(value); } /** * Sets the focus to the cell editor's label. */ @Override protected void doSetFocus() { editorLabel.setFocus(); } /** * Opens the dialog that suits the type provided by the configuration * parameter description. * * @return the selected value, or <code>null</code> if the dialog was * canceled or no selection was made in the dialog */ private Object openDialog() { if (configParamDesc == null) { return null; } String result = null; String oldValue = (String) value; boolean needCharConversion = false; Shell shell = editorComposite.getShell(); if (configParamDesc.isADirectory()) { result = openDirectoryDialog(shell, oldValue); needCharConversion = result != null; } else if (configParamDesc.isAFile()) { result = openFileDialog(shell, oldValue); needCharConversion = result != null; } else if (configParamDesc.isASet()) { ConfigParamSetEditingDialog dialog = new ConfigParamSetEditingDialog(shell, configParamDesc, editorLabel.getText()); if (dialog.open() == Window.OK) { result = dialog.getResult(); } } return needCharConversion ? ((String) result).replace('\\', '/') : result; } private String openDirectoryDialog(Shell shell, String oldValue) { DirectoryDialog dialog = new DirectoryDialog(shell); dialog.setFilterPath(oldValue); dialog.setText("Edit " + configParamDesc.getName()); dialog.setMessage("Choose a directory for '" + configParamDesc.getName() + "':"); return dialog.open(); } private String openFileDialog(Shell shell, String oldValue) { FileDialog dialog = new FileDialog(shell, SWT.OPEN); String defaultFileName = configParamDesc.getDefaultFileName(); boolean useOldValue = oldValue != null && !oldValue.isEmpty(); dialog.setFileName(useOldValue ? oldValue : defaultFileName); dialog.setText("Edit " + configParamDesc.getName()); dialog.setFilterExtensions(configParamDesc.getFileExtensions()); return dialog.open(); } /** * Lets the user edit the value via a custom dialog depending on the * parameter type. */ private void editValue() { Control previousFocusControl = Display.getCurrent().getFocusControl(); Object newValue = openDialog(); if (previousFocusControl != null && !previousFocusControl.isFocusControl()) { previousFocusControl.forceFocus(); } if (newValue != null) { boolean newValidState = isCorrect(newValue); if (newValidState) { markDirty(); doSetValue(newValue); } else { String msg = MessageFormat.format(getErrorMessage(), new Object[] { newValue.toString() }); setErrorMessage(msg); } fireApplyEditorValue(); } else { fireCancelEditor(); } } /** * Updates the label showing the value of this cell editor. * * @param value * the new value of this cell editor */ private void updateLabel(Object value) { if (editorLabel == null) { return; } String text = ""; //$NON-NLS-1$ if (value != null) { text = value.toString(); } editorLabel.setText(text); } }