| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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.apache.uima.taeconfigurator.editors.ui.dialogs; |
| |
| import java.util.Arrays; |
| import java.util.Comparator; |
| import java.util.Set; |
| |
| import org.apache.uima.taeconfigurator.StandardStrings; |
| import org.apache.uima.taeconfigurator.editors.MultiPageEditor; |
| import org.apache.uima.taeconfigurator.editors.MultiPageEditorContributor; |
| import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; |
| import org.eclipse.jface.dialogs.Dialog; |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.custom.CCombo; |
| import org.eclipse.swt.events.KeyEvent; |
| import org.eclipse.swt.events.KeyListener; |
| import org.eclipse.swt.graphics.FontData; |
| import org.eclipse.swt.graphics.Point; |
| 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.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Event; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Listener; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.swt.widgets.Table; |
| import org.eclipse.swt.widgets.TableItem; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.swt.widgets.Tree; |
| |
| public abstract class AbstractDialog extends Dialog implements Listener, StandardStrings { |
| |
| private final static boolean contentAssistAvailable; |
| static { |
| boolean contentAssistIsOK = false; |
| try { |
| Class.forName("org.eclipse.ui.fieldassist.ContentAssistField"); |
| contentAssistIsOK = true; |
| } catch (ClassNotFoundException e) { |
| } |
| contentAssistAvailable = contentAssistIsOK; |
| } |
| |
| protected MultiPageEditor editor; |
| |
| protected AbstractSection section; |
| |
| protected Button okButton; |
| |
| protected Label errorMessageUI; |
| |
| protected String title; |
| |
| protected String dialogDescription; |
| |
| /** |
| * @param parentShell |
| */ |
| protected AbstractDialog(AbstractSection section, String title, String description) { |
| // maintainers: don't use new shell; see comment in Dialog class |
| super(section.getSection().getShell()); |
| commonInit(section, title, description); |
| } |
| |
| protected AbstractDialog(Shell shell, String title, String description) { |
| super(shell); |
| commonInit(null, title, description); |
| } |
| |
| private void commonInit(AbstractSection aSection, String aTitle, String aDescription) { |
| section = aSection; |
| editor = (null == section)? null : section.editor; |
| setShellStyle(getShellStyle() | SWT.RESIZE); |
| title = aTitle; |
| dialogDescription = aDescription; |
| } |
| |
| public void setTitle(String title) { |
| this.title = title; |
| } |
| |
| public void setMessage(String msg) { |
| this.dialogDescription = msg; |
| } |
| protected Control createDialogArea(Composite parent) { |
| // create composite |
| Composite composite = (Composite) super.createDialogArea(parent); |
| createWideLabel(composite, dialogDescription); |
| return composite; |
| } |
| |
| protected Control createDialogArea(Composite parent, Object existing) { |
| Composite composite = (Composite) super.createDialogArea(parent); |
| createWideLabel(composite, dialogDescription); |
| if (null != existing) |
| getShell().setText(getShell().getText().replaceFirst("Add", "Edit")); |
| return composite; |
| } |
| |
| protected void configureShell(Shell shell) { |
| super.configureShell(shell); |
| shell.setText(title); |
| } |
| |
| protected Label createWideLabel(Composite parent, String message) { |
| Label label = null; |
| |
| label = new Label(parent, SWT.WRAP); |
| label.setText(null != message ? message : ""); |
| GridData data = new GridData(GridData.FILL_HORIZONTAL); |
| data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH); |
| label.setLayoutData(data); |
| return label; |
| } |
| |
| protected void createButtonsForButtonBar(Composite parent) { |
| super.createButtonsForButtonBar(parent); |
| okButton = getButton(IDialogConstants.OK_ID); |
| okButton.setEnabled(false); |
| } |
| |
| public static final String[] stringArray0 = new String[0]; |
| |
| protected void setTextAndTip(Button c, String label, String tip) { |
| c.setText(label); |
| c.setToolTipText(tip); |
| } |
| |
| protected void setTextAndTip(CCombo c, String label, String tip) { |
| c.setText(label); |
| c.setToolTipText(tip); |
| } |
| |
| protected void setTextAndTip(Label c, String label, String tip) { |
| c.setText(label); |
| c.setToolTipText(tip); |
| } |
| |
| protected Composite new2ColumnComposite(Composite parent) { |
| Composite twoCol = new Composite(parent, SWT.NONE); |
| twoCol.setLayout(new GridLayout(2, false)); // false = not equal width |
| ((GridLayout) twoCol.getLayout()).marginHeight = 0; |
| ((GridLayout) twoCol.getLayout()).marginWidth = 0; |
| twoCol.setLayoutData(new GridData(GridData.FILL_BOTH)); |
| return twoCol; |
| } |
| |
| protected Text newDescription(Composite twoCol, String tip) { |
| setTextAndTip(new Label(twoCol, SWT.NONE), S_DESCRIPTION, tip); |
| Text t = new Text(twoCol, SWT.BORDER | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL); |
| t.setLayoutData(new GridData(GridData.FILL_BOTH)); |
| ((GridData) t.getLayoutData()).heightHint = 100; |
| t.setToolTipText(tip); |
| return t; |
| } |
| |
| protected CCombo newLabeledCCombo(Composite parent, String label, String tip) { |
| setTextAndTip(new Label(parent, SWT.NONE), label, tip); |
| return newCCombo(parent, tip); |
| } |
| |
| protected CCombo newCCombo(Composite parent, String tip) { |
| final CCombo cc = new CCombo(parent, SWT.FLAT | SWT.BORDER | SWT.READ_ONLY); |
| cc.setBackground(getShell().getDisplay().getSystemColor(SWT.COLOR_WHITE)); |
| cc.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| // without these next lines, the height of the ccombo is too small |
| // especially on a Mac |
| FontData [] fontData = cc.getFont().getFontData(); |
| ((GridData) cc.getLayoutData()).heightHint = 2 * fontData[0].getHeight(); |
| cc.addListener(SWT.Selection, this); |
| cc.setToolTipText(tip); |
| cc.addKeyListener(new KeyListener() { |
| private final StringBuffer b = new StringBuffer(); |
| |
| public void keyPressed(KeyEvent e) { |
| } |
| |
| public void keyReleased(KeyEvent e) { |
| if (e.keyCode == SWT.BS) { |
| if (b.length() > 0) |
| b.deleteCharAt(b.length() - 1); |
| } else if (Character.isJavaIdentifierPart(e.character) || e.character == '.') |
| b.append(e.character); |
| else |
| return; |
| final String[] ccItems = cc.getItems(); |
| final String partial = b.toString(); |
| int iBefore = -1; |
| for (int i = 0; i < ccItems.length; i++) { |
| if (ccItems[i].startsWith(partial)) { |
| iBefore = i; |
| break; |
| } |
| } |
| if (iBefore >= 0) |
| cc.setText(cc.getItem(iBefore)); |
| } |
| }); |
| return cc; |
| } |
| |
| protected Button newButton(Composite parent, int style, String name, String tip) { |
| Button b = new Button(parent, style); |
| setTextAndTip(b, name, tip); |
| b.addListener(SWT.Selection, this); |
| return b; |
| } |
| |
| protected Text newText(Composite parent, int style, String tip) { |
| Text t = new Text(parent, style | SWT.BORDER); |
| t.setToolTipText(tip); |
| t.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| t.addListener(SWT.KeyUp, this); |
| t.addListener(SWT.MouseUp, this); // for paste operation |
| return t; |
| } |
| |
| protected Text newLabeledText(Composite parent, int style, String label, String tip) { |
| setTextAndTip(new Label(parent, SWT.NONE), label, tip); |
| return newText(parent, style, tip); |
| } |
| |
| protected Tree newTree(Composite parent, int style) { |
| Tree tree = new Tree(parent, style | SWT.BORDER); |
| GridData gd = new GridData(GridData.FILL_BOTH); |
| tree.setLayoutData(gd); |
| return tree; |
| } |
| |
| /** |
| * Styles = SWT.SINGLE / MULTI / CHECK / FULL_SELECTION / HIDE_SELECTION |
| * |
| * @param parent |
| * @param style |
| * @return the new table widget |
| */ |
| protected Table newTable(Composite parent, int style) { |
| Table table = new Table(parent, style | SWT.BORDER); |
| GridData gd = new GridData(GridData.FILL_BOTH); |
| table.setLayoutData(gd); |
| table.addListener(SWT.Selection, this); |
| table.addListener(SWT.KeyUp, this); // delete key |
| return table; |
| } |
| |
| public int getHitColumn(TableItem item, Point p) { |
| for (int i = item.getParent().getColumnCount() - 1; i >= 0; i--) { |
| Rectangle columnBounds = item.getBounds(i); |
| if (columnBounds.contains(p)) |
| return i; |
| } |
| return -1; |
| } |
| |
| public Composite newButtonContainer(Composite parent) { |
| Composite buttonContainer = new Composite(parent, SWT.NONE); |
| buttonContainer.setLayout(new GridLayout()); |
| buttonContainer.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING |
| | GridData.HORIZONTAL_ALIGN_FILL)); |
| return buttonContainer; |
| } |
| |
| public Button newPushButton(Composite parent, String label, String tip) { |
| Button button = new Button(parent, SWT.PUSH); |
| button.setText(label); |
| button.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING |
| | GridData.HORIZONTAL_ALIGN_FILL)); |
| // button.pack(); |
| button.setToolTipText(tip); |
| button.addListener(SWT.Selection, this); |
| return button; |
| } |
| |
| protected void newErrorMessage(Composite c) { |
| newErrorMessage(c, 1); |
| } |
| |
| protected void newErrorMessage(Composite twoCol, int span) { |
| Label m = new Label(twoCol, SWT.WRAP); |
| m.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| ((GridData) m.getLayoutData()).horizontalSpan = span; |
| ((GridData) m.getLayoutData()).widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH); |
| errorMessageUI = m; |
| } |
| |
| protected void setErrorMessage(String msg) { |
| errorMessageUI.setText(msg); |
| Composite shell = errorMessageUI.getParent(); |
| while (!(shell instanceof Shell)) |
| shell = shell.getParent(); |
| shell.setSize(shell.computeSize(-1, -1)); |
| } |
| |
| // subclasses override, and often use super.handleEvent to call this |
| public void handleEvent(Event event) { |
| if (okButton != null) // may be null if handler called from |
| // main area setText event, during construction |
| // because button bar is constructed after main area |
| enableOK(); |
| } |
| |
| protected void superButtonPressed(int buttonId) { |
| super.buttonPressed(buttonId); |
| } |
| |
| // overridden where needed |
| protected void buttonPressed(int buttonId) { |
| if (buttonId == IDialogConstants.OK_ID) { |
| copyValuesFromGUI(); |
| if (!isValid()) |
| return; // keeps dialog open |
| } |
| super.buttonPressed(buttonId); |
| } |
| |
| public abstract void copyValuesFromGUI(); |
| |
| public abstract boolean isValid(); |
| |
| protected Control createButtonBar(Composite c) { |
| Control returnValue = super.createButtonBar(c); |
| enableOK(); |
| return returnValue; |
| } |
| |
| public abstract void enableOK(); |
| |
| public boolean useQualifiedTypes() { |
| return MultiPageEditorContributor.getUseQualifiedTypes(); |
| } |
| |
| protected String[] getAllTypesAsSortedArray() { |
| String[] allTypes = (String[]) section.editor.allTypes.get().keySet().toArray(stringArray0); |
| Arrays.sort(allTypes, new Comparator() { |
| public int compare(Object o1, Object o2) { |
| String shortName1 = AbstractSection.getShortName((String) o1); |
| String shortName2 = AbstractSection.getShortName((String) o2); |
| if (!shortName1.equals(shortName2)) |
| return shortName1.compareTo(shortName2); |
| |
| String namespace1 = AbstractSection.getNameSpace((String) o1); |
| String namespace2 = AbstractSection.getNameSpace((String) o2); |
| return namespace1.compareTo(namespace2); |
| } |
| }); |
| return allTypes; |
| } |
| |
| protected Text newLabeledTypeInput(AbstractSection aSection, Composite parent, String label, String tip) { |
| setTextAndTip(new Label(parent, SWT.NONE), label, tip); |
| return newTypeInput(aSection, parent); |
| } |
| |
| /** |
| * @param twoCol |
| */ |
| protected Text newTypeInput(AbstractSection aSection, Composite twoCol) { |
| Composite tc = new2ColumnComposite(twoCol); |
| final TypesWithNameSpaces candidatesToPickFrom = getTypeSystemInfoList(); // provide an ArrayList of |
| |
| final Text text; |
| if (contentAssistAvailable) { |
| ContentAssistField32 caf = new ContentAssistField32(tc, candidatesToPickFrom); |
| text = caf.getControl(); |
| } else { |
| text = newText(tc, SWT.BORDER, ""); |
| } |
| |
| text.setToolTipText("Enter a Type name." + (contentAssistAvailable ? |
| "Content Assist is available (press Ctrl + Space)" : "")); |
| text.getParent().setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| text.addListener(SWT.KeyUp, this); |
| text.addListener(SWT.MouseUp, this); // for paste operation |
| text.addListener(SWT.Modify, this); // for content assist |
| |
| // newText(tc, SWT.NONE, |
| // "Enter a Type name. Content Assist is available on Eclipse 3.2 and beyond (press Ctrl + Space)"); |
| |
| // ContentProposalAdapter adapter = new ContentProposalAdapter( |
| // text, new TextContentAdapter(), |
| // candidatesToPickFrom, |
| // contentAssistActivationKey, |
| // contentAssistActivationChars); |
| // adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE); |
| |
| Button browseButton = newPushButton(tc, "Browse", "Click here to browse possible types"); |
| browseButton.removeListener(SWT.Selection, this); |
| final AbstractSection finalSection = aSection; |
| browseButton.addListener(SWT.Selection, new Listener() { |
| public void handleEvent(Event event) { |
| errorMessageUI.setText(""); |
| SelectTypeDialog dialog = new SelectTypeDialog(finalSection, candidatesToPickFrom); |
| // OpenTypeSystemSelectionDialog dialog = |
| // new OpenTypeSystemSelectionDialog(getShell(), typeList); |
| if (dialog.open() != IDialogConstants.OK_ID) |
| return; |
| |
| text.setText((null == dialog.nameSpaceName || |
| "".equals(dialog.nameSpaceName)) ? |
| dialog.typeName : |
| dialog.nameSpaceName + "." + dialog.typeName); |
| if (okButton != null) |
| enableOK(); |
| /* |
| Object[] types = dialog.getResult(); |
| if (types != null && types.length > 0) { |
| ITypeSystemInfo selectedType = (ITypeSystemInfo) types[0]; |
| text.setText(selectedType.getFullName()); |
| enableOK(); |
| } |
| */ |
| } |
| }); |
| /* |
| TypeSystemCompletionProcessor processor = new TypeSystemCompletionProcessor( |
| candidatesToPickFrom); |
| ControlContentAssistHelper.createTextContentAssistant(text, processor); |
| text.addListener(SWT.KeyDown, new Listener() { |
| public void handleEvent(Event e) { |
| errorMessageUI.setText(""); |
| } |
| }); |
| text.addListener(SWT.Modify, new Listener() { |
| public void handleEvent(Event e) { |
| textModifyCallback(e); |
| } |
| }); |
| */ |
| return text; |
| } |
| |
| public void textModifyCallback(Event e) { |
| } |
| |
| // default implementation - always overridden when used |
| public TypesWithNameSpaces getTypeSystemInfoList() { |
| return new TypesWithNameSpaces(); |
| } |
| |
| protected boolean typeContainedInTypeSystemInfoList(String fullTypeName, TypesWithNameSpaces types) { |
| String key = AbstractSection.getShortName(fullTypeName); |
| String nameSpace = AbstractSection.getNameSpace(fullTypeName); |
| |
| Set s = (Set)types.sortedNames.get(key); |
| |
| if (null == s) |
| return false; |
| |
| return s.contains(nameSpace); |
| } |
| |
| /** |
| * In XML, a 0 - length string is represented as <xxx/>, while a null value causes the element to |
| * be omitted. Fix up values to be null if empty. |
| * |
| * @param v |
| * @return null for 0 length string |
| */ |
| public static String nullIf0lengthString(String v) { |
| if ("".equals(v)) |
| return null; |
| return v; |
| } |
| |
| public static String convertNull(String v) { |
| if (null == v) |
| return ""; |
| return v; |
| } |
| } |