Java tutorial
/******************************************************************************* * Copyright (C) 2003-2006, 2013, Guillaume Brocker * Copyright (C) 2015-2016, Andre Bossert * * 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: * Guillaume Brocker - Initial API and implementation * Andre Bossert - moved and improved dialog code to CustomDoxygenDialog * - added support of eclipse variables to resolve doxygen path * ******************************************************************************/ package eclox.core.ui; import java.util.Collection; import java.util.Iterator; import java.util.Vector; import org.eclipse.jface.preference.FieldEditor; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.ui.ISharedImages; import org.eclipse.ui.PlatformUI; import eclox.core.IPreferences; import eclox.core.Plugin; import eclox.core.doxygen.BundledDoxygen; import eclox.core.doxygen.CustomDoxygen; import eclox.core.doxygen.DefaultDoxygen; import eclox.core.doxygen.Doxygen; /** * @author Guillaume Brocker */ public class DefaultDoxygenFieldEditor extends FieldEditor { /** * defines the version column index */ private final int VERSION_COLUMN_INDEX = 0; /** * defines the type column index */ private final int TYPE_COLUMN_INDEX = 1; /** * defines the description column index */ private final int DESCRIPTION_COLUMN_INDEX = 2; /** * the table control showing available doxygen wrappers */ private Table table; /** * the composite containing all buttons */ private Composite buttons; /** * the button that triggers the addition of a custom doxygen */ private Button add; /** * the button that triggers the edition of a custom doxygen */ private Button edit; /** * the button that triggers the removal of a custom doxygen */ private Button remove; /** * the valid state of the field editor */ private boolean valid = true; /** * Implements a selection listener for the owned table control. * * It is reponsible to ensure that only one table item is selected at a time * and it also fires value change notifications. */ private class MySelectionListener implements SelectionListener { /** * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) */ public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } /** * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ public void widgetSelected(SelectionEvent e) { if (e.item instanceof TableItem) onItemSelected((TableItem) e.item); else if (e.getSource() == add) onAddSelected(); else if (e.getSource() == edit) onEditSelected(); else if (e.getSource() == remove) onRemoveSelected(); } } /** * Adds a new table item for the given doxygen instance */ private void addItem(Doxygen doxygen) { TableItem item = new TableItem(table, 0); item.setData(doxygen); updateItem(item); } /** * Retrieves the type of the given doxygen wrapper instance */ private static String getDoxygenType(final Doxygen doxygen) { if (doxygen instanceof DefaultDoxygen) return "Default"; else if (doxygen instanceof CustomDoxygen) return "Custom"; else if (doxygen instanceof BundledDoxygen) return "Bundled"; else return "Uknown"; } /** * Updates the given table item. */ private void updateItem(TableItem item) { // Item data preparation. final Doxygen doxygen = (Doxygen) item.getData(); final String type = getDoxygenType(doxygen); final String version = doxygen.getVersion(); final String description = doxygen.getDescription(); // Updates the item properties. item.setImage((version == null) ? PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJS_WARN_TSK) : null); item.setText(VERSION_COLUMN_INDEX, (version == null) ? "unknown" : version); item.setText(TYPE_COLUMN_INDEX, type); item.setText(DESCRIPTION_COLUMN_INDEX, description); // Updates the table layout. table.getColumn(VERSION_COLUMN_INDEX).pack(); table.getColumn(TYPE_COLUMN_INDEX).pack(); table.getColumn(DESCRIPTION_COLUMN_INDEX).pack(); table.layout(); } /** * Checkes the table item representing the given doxygen identifier. */ private void checkItem(final String identifier) { TableItem[] items = table.getItems(); for (int i = 0; i < items.length; ++i) { Doxygen current = (Doxygen) items[i].getData(); items[i].setChecked(current.getIdentifier().equalsIgnoreCase(identifier)); } } /** * Retrieves checked items. * * @return the checked item or null if none */ private TableItem[] getCheckedItems() { // Pre-condition assert (table != null); Vector<TableItem> checked = new Vector<TableItem>(); TableItem[] items = table.getItems(); for (int i = 0; i < items.length; ++i) { if (items[i].getChecked() == true) { checked.add(items[i]); } } return (TableItem[]) checked.toArray(new TableItem[0]); } /** * Process the click on the add button. */ private void onAddSelected() { // Asks the user to select a location containing a doxygen binary. CustomDoxygenDialog dialog = new CustomDoxygenDialog(getPage().getShell(), null); dialog.open(); String directory = dialog.getTargetDirectory(); if (directory != null) { addItem(new CustomDoxygen(directory)); } } /** * Process the click on the edit button */ private void onEditSelected() { // Pre-condition assert (table != null); // Retrieves the checked items TableItem[] selected = table.getSelection(); // Retrieves the doxygen wrapper associated to the selected item assert (selected.length == 1); Doxygen doxygen = (Doxygen) selected[0].getData(); // Asks the user to select a location containing a doxygen binary. assert (doxygen instanceof CustomDoxygen); CustomDoxygen customDoxygen = (CustomDoxygen) doxygen; CustomDoxygenDialog dialog = new CustomDoxygenDialog(getPage().getShell(), customDoxygen.getLocation()); dialog.open(); String directory = dialog.getTargetDirectory(); if (directory != null) { customDoxygen.setLocation(directory); updateItem(selected[0]); } } /** * Process the click on the remove button */ private void onRemoveSelected() { // Pre-condition assert (table != null); table.remove(table.getSelectionIndex()); refreshValidState(); } /** * Process the selection of the given table item. */ private void onItemSelected(TableItem item) { if (item.getChecked() == true) { TableItem[] checked = getCheckedItems(); // Updates checked items so that only one is checked at the same time. for (int i = 0; i < checked.length; ++i) { if (checked[i] != item) { checked[i].setChecked(false); } } // Selects the item that has been checked. table.setSelection(table.indexOf(item)); // TODO only supported in eclipse 3.2 // table.setSelection( item ); // Fires some notifications. fireValueChanged(VALUE, null, null); } // Updates button states final boolean enable = item.getData() instanceof CustomDoxygen; edit.setEnabled(enable); remove.setEnabled(enable); // Refreshes the field validity. refreshValidState(); } /** * @see org.eclipse.jface.preference.FieldEditor#adjustForNumColumns(int) */ protected void adjustForNumColumns(int numColumns) { // Pre-condition assert (table != null); GridData tableData = (GridData) table.getLayoutData(); GridData buttonsData = (GridData) buttons.getLayoutData(); tableData.horizontalSpan = numColumns - 1; buttonsData.horizontalSpan = 1; } /** * @see org.eclipse.jface.preference.FieldEditor#doFillIntoGrid(org.eclipse.swt.widgets.Composite, int) */ protected void doFillIntoGrid(Composite parent, int numColumns) { // Pre-condition assert (table == null); // Creates the combo controls containing all available doxygen wrappers. GridData tableData = new GridData(GridData.FILL_BOTH); table = new Table(parent, SWT.SINGLE | SWT.CHECK | SWT.BORDER | SWT.FULL_SELECTION); tableData.horizontalSpan = numColumns - 1; table.setLayoutData(tableData); table.addSelectionListener(new MySelectionListener()); TableColumn versionColumn = new TableColumn(table, SWT.LEFT, VERSION_COLUMN_INDEX); TableColumn typeColumn = new TableColumn(table, SWT.LEFT, TYPE_COLUMN_INDEX); TableColumn descriptionColumn = new TableColumn(table, SWT.LEFT, DESCRIPTION_COLUMN_INDEX); versionColumn.setText("Version"); typeColumn.setText("Type"); descriptionColumn.setText("Description"); table.setHeaderVisible(true); // Creates the composite containing all buttons and located on the right side of the table. GridData buttonsData = new GridData(GridData.END); FillLayout buttonsLayout = new FillLayout(SWT.VERTICAL); buttons = new Composite(parent, SWT.NO_FOCUS); buttonsData.horizontalSpan = 1; buttonsData.horizontalAlignment = SWT.FILL; buttons.setLayoutData(buttonsData); buttonsLayout.spacing = 5; buttons.setLayout(buttonsLayout); // Creates the button controlling custom doyxgen wrappers. add = new Button(buttons, SWT.PUSH); edit = new Button(buttons, SWT.PUSH); remove = new Button(buttons, SWT.PUSH); add.setText("Add..."); add.addSelectionListener(new MySelectionListener()); edit.setText("Edit..."); edit.addSelectionListener(new MySelectionListener()); edit.setEnabled(false); remove.setText("Remove"); remove.addSelectionListener(new MySelectionListener()); remove.setEnabled(false); } /** * @see org.eclipse.jface.preference.FieldEditor#doLoad() */ protected void doLoad() { // Adds default doxygen instance. addItem(new DefaultDoxygen()); // Adds custom doxygens. final String raw = getPreferenceStore().getString(IPreferences.CUSTOM_DOXYGENS); final String[] splitted = raw.split("\n"); for (int i = 0; i < splitted.length; ++i) { Doxygen doxygen = Doxygen.getFromClassAndIdentifier(CustomDoxygen.class, splitted[i]); if (doxygen != null) { addItem(doxygen); } else { Plugin.getDefault().logError(splitted[i] + ": invalid custom doxygen identifier found."); } } // Adds bundled doxygens. Collection<?> bundled = BundledDoxygen.getAll(); Iterator<?> i = bundled.iterator(); while (i.hasNext()) { addItem((Doxygen) i.next()); } // Select the default doxygen wrapper checkItem(getPreferenceStore().getString(IPreferences.DEFAULT_DOXYGEN)); } /** * @see org.eclipse.jface.preference.FieldEditor#doLoadDefault() */ protected void doLoadDefault() { // Adds default doxygen instance. addItem(new DefaultDoxygen()); // Select the default doxygen wrapper checkItem(getPreferenceStore().getDefaultString(IPreferences.DEFAULT_DOXYGEN)); } /** * @see org.eclipse.jface.preference.FieldEditor#doStore() */ protected void doStore() { // Pre-condition assert (table != null); // Saves all custom doxygen wrappers. TableItem[] items = table.getItems(); String serialized = new String(); for (int i = 0; i < items.length; ++i) { Object itemData = items[i].getData(); if (itemData instanceof CustomDoxygen) { CustomDoxygen doxygen = (CustomDoxygen) itemData; serialized = serialized.concat(doxygen.getIdentifier()); serialized = serialized.concat("\n"); } } getPreferenceStore().setValue(IPreferences.CUSTOM_DOXYGENS, serialized); // Saves the checked item. TableItem[] checked = getCheckedItems(); String defaultDoxygen = new String(); if (checked.length == 1) { Doxygen doxygen = (Doxygen) checked[0].getData(); defaultDoxygen = doxygen.getIdentifier(); } getPreferenceStore().setValue(IPreferences.DEFAULT_DOXYGEN, defaultDoxygen); } /** * @see org.eclipse.jface.preference.FieldEditor#refreshValidState() */ protected void refreshValidState() { TableItem[] checked = getCheckedItems(); boolean oldValid = valid; boolean newValid = checked.length == 1; // Updates validity and error message. valid = newValid; if (valid == false) { showErrorMessage("Select the doxygen version to use."); } else { clearErrorMessage(); } // Send some notifications. if (newValid != oldValid) { fireStateChanged(IS_VALID, oldValid, newValid); } } /** * Constructor */ public DefaultDoxygenFieldEditor(Composite parent) { super(IPreferences.DEFAULT_DOXYGEN, "Doxygen:", parent); } /** * @see org.eclipse.jface.preference.FieldEditor#getNumberOfControls() */ public int getNumberOfControls() { return 2; } /** * @see org.eclipse.jface.preference.FieldEditor#isValid() */ public boolean isValid() { return valid; } /** * @see org.eclipse.jface.preference.FieldEditor#setFocus() */ public void setFocus() { super.setFocus(); table.setFocus(); } }