Java tutorial
/* * Copyright (c) 2010-2012 Research In Motion Limited. All rights reserved. * * This program and the accompanying materials are made available * under the terms of the Eclipse Public License, Version 1.0, * which accompanies this distribution and is available at * * http://www.eclipse.org/legal/epl-v10.html * */ package net.rim.ejde.internal.ui.editors.model; import java.util.ArrayList; import java.util.Arrays; import java.util.Hashtable; import java.util.Iterator; import java.util.Map; import net.rim.ejde.internal.core.IConstants; import net.rim.ejde.internal.model.BasicBlackBerryProperties.Icon; import net.rim.ejde.internal.model.BasicBlackBerryProperties.PreprocessorTag; import net.rim.ejde.internal.model.BlackBerryProject; import net.rim.ejde.internal.util.Messages; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.FocusListener; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; import org.eclipse.ui.forms.AbstractFormPart; import org.eclipse.ui.forms.SectionPart; import org.eclipse.ui.forms.editor.FormEditor; import org.eclipse.ui.forms.editor.FormPage; /** * This is the base class for all pages within the project application descriptor editor. It provides various helper methods used * through out the pages. * * @author cmalinescu, jkeshavarzi * */ public abstract class BlackBerryProjectPropertiesPage extends FormPage { public static final String CONTROL_TITLE_KEY = "TITLE"; //$NON-NLS-1$ public static final String TABLE_TEXT_INDEX_KEY = "TEXT_COLUMN"; //$NON-NLS-1$ public static final String SECTION_PART_KEY = "part"; //$NON-NLS-1$ private final BlackBerryProject _blackBerryProject; private ArrayList<SectionPart> sections = new ArrayList<SectionPart>(); /** * The actions associated with each button event used in the editor * * @author jkeshavarzi * */ public static enum Action { ADD, ADD_FROM_PROJECT, ADD_FROM_EXTERNAL, REMOVE, EDIT, SELECT_ALL, SELECT_NONE, BROWSE, MOVE_UP, MOVE_DOWN; public String getButtonLabel() { switch (this) { case ADD: return Messages.BlackBerryProjectPropertiesPage_Add_Button_Label; case REMOVE: return Messages.BlackBerryProjectPropertiesPage_Remove_Button_Label; case EDIT: return Messages.BlackBerryProjectPropertiesPage_Edit_Button_Label; case ADD_FROM_PROJECT: return Messages.BlackBerryProjectPropertiesPage_Add_From_Project_Button_Label; case ADD_FROM_EXTERNAL: return Messages.BlackBerryProjectPropertiesPage_Add_From_External_Button_Label; case SELECT_ALL: return Messages.BlackBerryProjectPropertiesPage_Select_All_Button_Label; case SELECT_NONE: return Messages.BlackBerryProjectPropertiesPage_Deselect_All_Button_Label; case BROWSE: return Messages.BlackBerryProjectPropertiesPage_Browse_Button_Label_Ellipsis; case MOVE_UP: return Messages.BlackBerryProjectPropertiesPage_MoveUp_Button_Label; case MOVE_DOWN: return Messages.BlackBerryProjectPropertiesPage_MoveDown_Button_Label; default: return IConstants.EMPTY_STRING; } } } /** * @param editor * @param id * @param title */ public BlackBerryProjectPropertiesPage(FormEditor editor, String id, String title) { super(editor, id, title); _blackBerryProject = ((BlackBerryProjectFormEditor) editor).getBlackBerryProject(); } protected void addSection(SectionPart part) { getManagedForm().addPart(part); sections.add(part); } protected SectionPart[] getSections() { return sections.toArray(new SectionPart[sections.size()]); } protected AbstractSection getSectionPartProperty(Composite body) { AbstractSection section = null; Object parent = body.getParent().getData(SECTION_PART_KEY); if (parent == null) { // if part cannot be found, check higher. Used in packaging section where there is another level of composite parents parent = body.getParent().getParent().getData(SECTION_PART_KEY); } if ((parent != null) && (parent instanceof AbstractSection)) { section = (AbstractSection) parent; } return section; } /** * @param keyTable * @return An array of he resource keys in the passed in resource */ protected String[] getResourceKeys(Hashtable<String, String> keyTable) { if (keyTable == null) { return new String[] {}; } ArrayList<String> keys = new ArrayList<String>(); // Add blank entry to key list to allow user to select none. keys.add(""); //$NON-NLS-1$ for (Iterator<String> iterator = keyTable.keySet().iterator(); iterator.hasNext();) { keys.add(iterator.next()); } return keys.toArray(new String[keys.size()]); } /** * Creates an error marker in the editor with the given key * * @param key * @param message * @param control */ public void createEditorErrorMarker(Object key, String message, Control control) { getManagedForm().getMessageManager().addMessage(key, message, null, IMessageProvider.ERROR, control); } /** * Creates a warning marker in the editor with the given key * * @param key * @param message * @param control */ public void createEditorWarnMarker(Object key, String message, Control control) { getManagedForm().getMessageManager().addMessage(key, message, null, IMessageProvider.WARNING, control); } /** * Removes an error marker in the editor specified by the given key * * @param key * @param control */ public void removeEditorErrorMarker(Object key, Control control) { getManagedForm().getMessageManager().removeMessage(key, control); } /** * Sets the editor and managed forms to dirty */ protected void notifyModelChanged() { ((BlackBerryProjectFormEditor) getEditor()).setDirty(true); getManagedForm().dirtyStateChanged(); } /** * Adds the given object item to the given table if and only if the object does not already exist. Also updates button * controls. * * @param viewer * @param item * @param actionButtons */ public boolean addTableItem(TableViewer viewer, Object item, Map<Action, Button> actionButtons, boolean updateUIOnly) { if (updateUIOnly) { if (actionButtons.containsKey(Action.EDIT)) { actionButtons.get(Action.EDIT).setEnabled(true); } if (actionButtons.containsKey(Action.REMOVE)) { actionButtons.get(Action.REMOVE).setEnabled(true); } return true; } else { if (getObjectIndexInViewer(viewer, item) == -1) { if (item != null) { viewer.add(item); Table table = viewer.getTable(); table.select(table.getItemCount() - 1); // Used to fire any selection events viewer.setSelection(viewer.getSelection()); } if (actionButtons.containsKey(Action.EDIT)) { actionButtons.get(Action.EDIT).setEnabled(true); } if (actionButtons.containsKey(Action.REMOVE)) { actionButtons.get(Action.REMOVE).setEnabled(true); } return true; } return false; } } /** * Sets the given viewer to the given input. Convenience method that removes all existing data before setting the input. * * @param viewer * @param input */ public void setViewerInput(TableViewer viewer, Object[] input) { Arrays.sort(input); // Remove existing data viewer.setInput(null); viewer.getTable().removeAll(); viewer.setInput(input); viewer.refresh(true); } /** * Helper method that locates the given itemText and if found selects it. * * @param viewer * @param itemText * @param actionButtons */ public void selectItemInViewer(TableViewer viewer, String itemText, Map<Action, Button> actionButtons) { Integer index = getItemIndex(viewer.getTable(), itemText); if (index != -1) { viewer.getTable().select(index); // Used to fire any selection events viewer.setSelection(viewer.getSelection()); if (actionButtons != null) { if (actionButtons.containsKey(Action.EDIT)) { actionButtons.get(Action.EDIT).setEnabled(true); } if (actionButtons.containsKey(Action.REMOVE)) { actionButtons.get(Action.REMOVE).setEnabled(true); } if (actionButtons.containsKey(Action.MOVE_UP)) { if (viewer.getTable().getItemCount() > 1) { actionButtons.get(Action.MOVE_UP).setEnabled(true); } } if (actionButtons.containsKey(Action.MOVE_DOWN)) { actionButtons.get(Action.MOVE_DOWN) .setEnabled(index < viewer.getTable().getItemCount() - 1 ? true : false); } } } } /** * Removes the currently selected table item from the viewer and updates controls accordingly * * @param viewer * @param actionButtons * @param updateUIOnly * <code>true</code> only update UI but not remove items from the table; <code>false</code> update UI and remove * items from the table; */ public void removeSelectedTableItem(TableViewer viewer, Map<Action, Button> actionButtons, boolean updateUIOnly) { StructuredSelection selection = (StructuredSelection) viewer.getSelection(); Table table = viewer.getTable(); int selectionIndex = table.getSelectionIndex(); Boolean entryRemoved = false; if (!updateUIOnly) { for (Iterator<?> iter = selection.iterator(); iter.hasNext();) { Object selectedElement = iter.next(); if (selectedElement != null) { viewer.remove(selectedElement); if (!entryRemoved) { entryRemoved = true; } } } } if (updateUIOnly || entryRemoved) { int itemCount = table.getItemCount(); if (itemCount != 0) { table.select(itemCount - 1 > selectionIndex ? selectionIndex : itemCount - 1); if (actionButtons.containsKey(Action.MOVE_DOWN)) { if (selectionIndex == itemCount - 1) { actionButtons.get(Action.MOVE_DOWN).setEnabled(false); } actionButtons.get(Action.MOVE_UP).setEnabled(itemCount > 1 ? true : false); } // Used to fire any selection events viewer.setSelection(viewer.getSelection()); } else { if (actionButtons.containsKey(Action.EDIT)) { actionButtons.get(Action.EDIT).setEnabled(false); } if (actionButtons.containsKey(Action.REMOVE)) { actionButtons.get(Action.REMOVE).setEnabled(false); } if (actionButtons.containsKey(Action.MOVE_UP)) { actionButtons.get(Action.MOVE_UP).setEnabled(false); } if (actionButtons.containsKey(Action.MOVE_DOWN)) { actionButtons.get(Action.MOVE_DOWN).setEnabled(false); } if (actionButtons.containsKey(Action.SELECT_ALL)) { actionButtons.get(Action.SELECT_ALL).setEnabled(false); } if (actionButtons.containsKey(Action.SELECT_NONE)) { actionButtons.get(Action.SELECT_NONE).setEnabled(false); } } // Enable any disabled add buttons - icon scenarios where only 2 icons can be added. if (actionButtons.containsKey(Action.ADD)) { actionButtons.get(Action.ADD).setEnabled(true); } if (actionButtons.containsKey(Action.ADD_FROM_PROJECT)) { actionButtons.get(Action.ADD_FROM_PROJECT).setEnabled(true); } if (actionButtons.containsKey(Action.ADD_FROM_EXTERNAL)) { actionButtons.get(Action.ADD_FROM_EXTERNAL).setEnabled(true); } if (table.getColumnCount() > 1) { table.getColumn(1).pack(); } } } /** * Searches the given viewer for the given object and returns its index or -1 if the object was not found * * @param viewer * @param obj * @return */ public Integer getObjectIndexInViewer(TableViewer viewer, Object obj) { for (int i = 0; i < viewer.getTable().getItemCount(); i++) { Object element = viewer.getElementAt(i); if ((obj instanceof Icon) && (element instanceof Icon)) { IProject project = _blackBerryProject.getProject(); IPath iconPath = new Path(((Icon) element).getCanonicalFileName()); IResource iconRes = project.findMember(iconPath); IPath projectPath = project.getLocation(), iconRelPath, iconAbsPath; if (iconRes != null) { iconRelPath = projectPath.append(iconRes.getProjectRelativePath()); iconAbsPath = iconRes.getLocation(); } else { iconRelPath = null; iconAbsPath = projectPath.append(iconPath); } IPath newIconPath = projectPath.append(((Icon) obj).getCanonicalFileName()); if (newIconPath.equals(iconRelPath) || newIconPath.equals(iconAbsPath)) { return i; } } else if ((obj instanceof PreprocessorTag) && (element instanceof PreprocessorTag)) { PreprocessorTag o1 = (PreprocessorTag) obj; PreprocessorTag o2 = (PreprocessorTag) element; if (o1.getPreprocessorDefine().equals(o2.getPreprocessorDefine())) { return i; } } else { if (obj.equals(element)) { return i; } } } return -1; } /** * Checks the given table for any items with the given text and returns the first found index * * @param table * @param itemText * @return The index or -1 if the text was not found */ public static Integer getItemIndex(Table table, String itemText) { Object obj = table.getData(TABLE_TEXT_INDEX_KEY); Integer textColumn = null; if ((obj != null) && (obj instanceof Integer)) { textColumn = (Integer) obj; for (int i = 0; i < table.getItemCount(); i++) { TableItem item = table.getItem(i); if (item.getText(textColumn).equals(itemText)) { return i; } } } return -1; } /** * Returns an instance of BlackBerryProject * * @return Instance of BlackBerryProject */ public BlackBerryProject getBlackBerryProject() { return _blackBerryProject; } public static boolean isImage(String fileName) { if (fileName.toLowerCase().matches(".*[.](gif|png|xpm|bmp|jpg|jpeg|tiff)")) { //$NON-NLS-1$ return true; } return false; } public static boolean isAlx(String fileName) { if (fileName.toLowerCase().matches(".*[.](alx)")) { //$NON-NLS-1$ return true; } return false; } /** * Dirty listener * * @author jkeshavarzi * */ public class DirtyListener implements ModifyListener, SelectionListener { AbstractFormPart _section = null; public DirtyListener(AbstractFormPart section) { _section = section; } @Override public void modifyText(ModifyEvent e) { process(); } @Override public void widgetDefaultSelected(SelectionEvent e) { process(); } @Override public void widgetSelected(SelectionEvent e) { process(); } public void process() { notifyModelChanged(); // The dirty flag must be set on the details rather than section so that changes made on it can be committed // see ManagedForm.commit() logic if (BlackBerryProjectPropertiesPage.this instanceof BlackBerryProjectAlternateEntryPointPage) { AlternateEntryPointDetails details = ((BlackBerryProjectAlternateEntryPointPage) BlackBerryProjectPropertiesPage.this) .getAlternateEntryPointDetails(); if (details != null) { details.markDirty(); } } else { _section.markDirty(); } } } /** * The parent listener to all button event listeners used in the editor * * @author jkeshavarzi * */ protected abstract class FilePathOperationSelectionListener implements SelectionListener { AbstractFormPart _section = null; protected FilePathOperationSelectionListener(AbstractFormPart section) { _section = section; } @Override public void widgetDefaultSelected(SelectionEvent e) { apply(e); } @Override public void widgetSelected(SelectionEvent e) { apply(e); } private void apply(SelectionEvent e) { if (process(e)) { notifyModelChanged(); if (_section != null) { _section.markDirty(); } } } protected abstract boolean process(SelectionEvent e); } /** * Project properties focus listener * * @author jkeshavarzi * */ protected class ProjectPropertiesFocusListener implements FocusListener { @Override public void focusLost(FocusEvent e) { // TODO Future implementation } @Override public void focusGained(FocusEvent e) { // Will be used in future outline View // BlackBerryProjectFormEditor editor = (BlackBerryProjectFormEditor) getEditor(); // editor.updateContentOutlinePageSelection( (Control) e.getSource() ); } } /** * The basic listener used in editor tables * * @author jkeshavarzi * */ protected static class TableSelectionListener implements SelectionListener { private Button remove, edit, moveUp, moveDown; public TableSelectionListener(Map<Action, Button> buttonMap) { remove = buttonMap.get(Action.REMOVE); edit = buttonMap.get(Action.EDIT); moveUp = buttonMap.get(Action.MOVE_UP); moveDown = buttonMap.get(Action.MOVE_DOWN); } @Override public void widgetDefaultSelected(SelectionEvent e) { } @Override public void widgetSelected(SelectionEvent e) { Table table = ((Table) e.getSource()); int selectionCount = table.getSelectionCount(); int selectionIndex = table.getSelectionIndex(); int itemCount = table.getItemCount(); if (edit != null) { if (selectionCount > 1) { edit.setEnabled(false); } else { edit.setEnabled(true); } } if (remove != null) { remove.setEnabled(true); } if (moveUp != null) { moveUp.setEnabled((itemCount > 1) && (selectionIndex > 0) ? true : false); } if (moveDown != null) { moveDown.setEnabled((itemCount > 1) && (selectionIndex < itemCount - 1) ? true : false); } } } }