id="net.sourceforge.phpeclipse.actions.showAction">
</action>
</objectContribution>
- <viewerContribution
- targetID="#PHPEditorContext"
- id="net.sourceforge.phpeclipse.actions.popup.editor">
- <action
- label="PHP Help"
- class="net.sourceforge.phpeclipse.actions.PHPEclipseShowContextHelp"
- menubarPath="additions"
- id="net.sourceforge.phpeclipse.actions.editor.contexthelp">
- </action>
- </viewerContribution>
</extension>
<extension
point="org.eclipse.ui.preferencePages">
id="net.sourceforge.phpeclipse.preference.PHPEclipsePreferencePage">
</page>
<page
- name="PHP Editor"
+ name="Editor"
category="net.sourceforge.phpeclipse.preference.PHPEclipsePreferencePage"
class="net.sourceforge.phpeclipse.PHPSyntaxPreferencePage"
id="net.sourceforge.phpeclipse.preference.PHPSyntaxPreferencePage">
<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
-(c) Copyright IBM Corp. 2000, 2001.
-All Rights Reserved.
--->
-
<templates>
-
- <!-- php -->
-
- <template description="iterate over array" name="for" context="php"
->for (int ${index} = 0; ${index} < ${array}.length; ${index}++) {
- ${cursor}
+<template name="class" description="class template with constructor" context="php" enabled="true">class ${class_name} {
+ function ${class_name}() {
+ ${cursor}
+ }
}</template>
+<template name="class" description="class with attribute" context="php" enabled="true">class ${class_name} {
+ var $$${attribute};
+ function ${class_name}() {
+ ${cursor}
+ }
+
+ function set_${attribute}( $$${attr} ) {
+ $$this->${attribute} = $$${attr};
+ }
- <template description="iterate over array w/ temporary variable" name="for" context="php"
->for (int ${index} = 0; ${index} < ${array}.length; ${index}++) {
- ${array_type} ${array_element} = ${array}[${index}];
- ${cursor}
+ function get_${attribute}() {
+ return $$this->${attribute};
+ }
}</template>
-
- <template description="iterate over collection" name="for" context="php"
->for (Iterator ${iterator} = ${collection}.iterator(); ${iterator}.hasNext(); ) {
- ${type} ${element} = (${type}) ${iterator}.next();
+<template name="for" description="iterate over array" context="php" enabled="true">for ($$${index} = 0; $$${index} < sizeof($$${array}); $$${index}++) {
${cursor}
}</template>
-
- <template description="iterate with enumeration" name="while" context="php"
->while (${enumeration}.hasMoreElements()) {
- ${type} ${element} = (${type}) ${enumeration}.nextElement();
+<template name="for" description="iterate over array w/ temporary variable" context="php" enabled="true">for ($$${index} = 0; $$${index} < sizeof($$${array}); $$${index}++) {
+ $$${array_element} = $$${array}[$$${index}];
${cursor}
}</template>
-
- <template description="iterate with iterator" name="while" context="php"
->while (${iterator}.hasNext()) {
- ${type} ${element} = (${type}) ${iterator}.next();
+<template name="function" description="function template" context="php" enabled="true">function ${function_name} () {
${cursor}
}</template>
-
- <template description="do while statement" name="do" context="php"
->do {
+<template name="function" description="function template with return" context="php" enabled="true">function ${function_name} () {
+ return (${cursor});
+}</template>
+<template name="while" description="while iteration" context="php" enabled="true">while (${condition}) {
${cursor}
-} while (${condition});</template>
-
- <template description="switch case statement" name="switch" context="php"
->switch (${key}) {
+}</template>
+<template name="switch" description="switch case statement" context="php" enabled="true">switch (${key}) {
case ${value}:
${cursor}
break;
default:
break;
-}</template>
-
- <template description="if statement" name="if" context="php"
->if (${condition}) {
+}</template><template name="if" description="if statement" context="php" enabled="true">if (${condition}) {
${cursor}
-}</template>
-
- <template description="if else statement" name="ifelse" context="php"
->if (${condition}) {
+}</template><template name="ifelse" description="if else statement" context="php" enabled="true">if (${condition}) {
${cursor}
} else {
-}</template>
-
- <template description="else if block" name="elseif" context="php"
->else if (${condition}) {
- ${cursor}
-}</template>
-
- <template description="else block" name="else" context="php"
->else {
- ${cursor}
-}</template>
-
- <template description="try catch block" name="try" context="php"
->try {
+}</template><template name="elseif" description="else if block" context="php" enabled="true">elseif (${condition}) {
${cursor}
-} catch (${Exception} e) {
-}</template>
-
- <template description="catch block" name="catch" context="php"
->catch (${Exception} e) {
- ${cursor}
-}</template>
-
- <template description="main method" name="main" context="php"
->
-public static void main(String[] args) {
- ${cursor}
-}</template>
-
- <template description="public method" name="public_method" context="php"
->
-public ${return_type} ${name}(${arguments}) {
+}</template><template name="else" description="else block" context="php" enabled="true">else {
${cursor}
}</template>
-
- <template description="protected method" name="protected_method" context="php"
->protected ${return_type} ${name}(${arguments}) {
- ${cursor}
-}</template>
-
- <template description="private method" name="private_method" context="php"
->private ${return_type} ${name}(${arguments}) {
- ${cursor}
-}</template>
-
- <template description="private static method" name="private_static_method" context="php"
->private static ${return_type} ${name}(${arguments}) {
- ${cursor}
-}</template>
-
- <template description="dynamic type test and cast" name="instanceof" context="php"
->if (${name} instanceof ${type}) {
- ${type} ${new_name} = (${type})${name};
- ${cursor}
-}</template>
-
- <template description="dynamic cast" name="cast" context="php"
->${type} ${new_name} = (${type}) ${name};
-</template>
-
- <template description="create new object" name="new" context="php"
->${type} ${name} = new ${type}(${arguments});
-</template>
-
- <template description="lazy creation" name="lazy" context="php"
->if (${name} == null) {
- ${name} = new ${type}(${arguments});
- ${cursor}
-}
-
-return ${name};
-</template>
-
- <template description="convert collection to array" name="toarray" context="php"
- >(${type}[]) ${collection}.toArray(new ${type}[${collection}.size()]);</template>
-
- <template context="php" description="file comment used by the class and interface wizards" enabled="true" name="filecomment">/**
- * Created on ${date}
+<template name="filecomment" description="file comment used by the class and interface wizards" context="php" enabled="true">/**
+ * Created on ${date} by ${user}
*
- * To change this generated comment edit the template variable "filecomment":
- * Window>Preferences>Java>Templates.
- * To enable and disable the creation of file comments go to
- * Window>Preferences>Java>Code Generation.
- */</template>
-
-<template name="typecomment" description="type comment used by the class and interface wizards" context="php" enabled="true">/**
+ */</template><template name="functioncomment" description="function comment" context="php" enabled="true">/**
* @author ${user}
*
- * To change this generated comment edit the template variable "typecomment":
- * Window>Preferences>Java>Templates.
- * To enable and disable the creation of type comments go to
- * Window>Preferences>Java>Code Generation.
- */</template>
-
- <template description="print to standard out" name="stdout" context="php"
- >System.out.println(${cursor});</template>
-
- <template description="print to standard error" name="stderr" context="php"
- >System.err.println(${cursor});</template>
-
- <!-- html -->
-
- <template description="<code></code>" name="<code>" context="html"
- ><code>${cursor}</code></template>
-
- <template description="<code>null</code>" name="<code>" context="html"
- ><code>null</code></template>
-
- <template description="<pre></pre>" name="<pre>" context="html"
- ><pre>${cursor}</pre></template>
-
- <template description="<b></b>" name="<b>" context="html"
- ><b>${cursor}</b></template>
-
- <template description="<i></i>" name="<i>" context="html"
- ><i>${cursor}</i></template>
-
- <template description="author name" name="@author" context="html"
- >@author ${user}</template>
-
-</templates>
+ */</template>
+ <template name="echo" description="echo a string" context="php" enabled="true">echo "${string}";
+ ${cursor}</template>
+ </templates>
\ No newline at end of file
return template.matches(getKey(), getContextType().getName());
}
+ /**
+ * Returns <code>true</code> if template matches the prefix and context,
+ * <code>false</code> otherwise.
+ */
+ public boolean canEvaluate(String identifier) {
+ String prefix = getKey();
+ return
+// fEnabled &&
+// fContextTypeName.equals(contextTypeName) &&
+ (prefix.length() != 0) &&
+ identifier.toLowerCase().startsWith(prefix.toLowerCase());
+ }
+
/*
* @see TemplateContext#evaluate(Template template)
*/
try {
int start= getCompletionPosition();
- while ((start != 0) && Character.isUnicodeIdentifierPart(document.getChar(start - 1)))
+ while ( ((start != 0) && Character.isUnicodeIdentifierPart(document.getChar(start - 1))) ||
+ ((start != 0) && document.getChar(start - 1)=='$') ) {
start--;
+ }
- if ((start != 0) && Character.isUnicodeIdentifierStart(document.getChar(start - 1)))
+ if ( ((start != 0) && Character.isUnicodeIdentifierStart(document.getChar(start - 1))) ||
+ ((start != 0) && document.getChar(start - 1)=='$')) {
start--;
+ }
return start;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import net.sourceforge.phpdt.internal.corext.util.Strings;
-import net.sourceforge.phpdt.internal.ui.JavaStatusConstants;
+import net.sourceforge.phpdt.internal.ui.PHPStatusConstants;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DefaultLineTracker;
import org.eclipse.jface.text.IDocument;
try {
fDocument.replace(offset, length, text);
} catch (BadLocationException e) {
- IStatus s = new Status(IStatus.ERROR, PHPeclipsePlugin.getPluginId(), JavaStatusConstants.INTERNAL_ERROR,
+ IStatus s = new Status(IStatus.ERROR, PHPeclipsePlugin.getPluginId(), PHPStatusConstants.INTERNAL_ERROR,
TextManipulationMessages.getFormattedString(
"TextBuffer.wrongRange", //$NON-NLS-1$
new Object[] {new Integer(offset), new Integer(length) } ), e);
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import net.sourceforge.phpdt.internal.corext.util.IOCloser;
-import net.sourceforge.phpdt.internal.ui.JavaStatusConstants;
+import net.sourceforge.phpdt.internal.ui.PHPStatusConstants;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.source.IAnnotationModel;
document.set(buffer.toString());
return new TextBuffer(document);
} catch (IOException x) {
- IStatus s= new Status(IStatus.ERROR, PHPeclipsePlugin.getPluginId(), JavaStatusConstants.INTERNAL_ERROR, x.getMessage(), x);
+ IStatus s= new Status(IStatus.ERROR, PHPeclipsePlugin.getPluginId(), PHPStatusConstants.INTERNAL_ERROR, x.getMessage(), x);
throw new CoreException(s);
} finally {
IOCloser.perform(in, stream);
private void throwNotManaged() throws CoreException {
IStatus s= new Status(IStatus.ERROR, PHPeclipsePlugin.getPluginId(),
- JavaStatusConstants.INTERNAL_ERROR, TextManipulationMessages.getString("TextBufferFactory.bufferNotManaged"), null); //$NON-NLS-1$
+ PHPStatusConstants.INTERNAL_ERROR, TextManipulationMessages.getString("TextBufferFactory.bufferNotManaged"), null); //$NON-NLS-1$
throw new CoreException(s);
}
}
package net.sourceforge.phpdt.internal.ui;
/**
- * Defines status codes relevant to the Java UI plug-in. When a
+ * Defines status codes relevant to the PHP UI plug-in. When a
* Core exception is thrown, it contain a status object describing
* the cause of the exception. The status objects originating from the
- * Java UI plug-in use the codes defined in this interface.
+ * PHP UI plug-in use the codes defined in this interface.
*/
-public class JavaStatusConstants {
+public class PHPStatusConstants {
// Prevent instantiation
- private JavaStatusConstants() {
+ private PHPStatusConstants() {
}
/** Status code describing an internal error */
* support
*/
-public class JavaUIException extends CoreException {
+public class PHPUIException extends CoreException {
- public JavaUIException(IStatus status) {
+ public PHPUIException(IStatus status) {
super(status);
}
}
\ No newline at end of file
import java.util.MissingResourceException;
import java.util.ResourceBundle;
-public class JavaUIMessages {
+public class PHPUIMessages {
- private static final String RESOURCE_BUNDLE= "org.eclipse.jdt.internal.ui.JavaUIMessages";//$NON-NLS-1$
+ private static final String RESOURCE_BUNDLE = PHPUIMessages.class.getName();//$NON-NLS-1$
private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE);
- private JavaUIMessages() {
+ private PHPUIMessages() {
}
public static String getString(String key) {
import org.eclipse.core.runtime.Status;
/**
- * Convenience class for error exceptions thrown inside JavaUI plugin.
+ * Convenience class for error exceptions thrown inside PHPUI plugin.
*/
-public class JavaUIStatus extends Status {
+public class PHPUIStatus extends Status {
- public JavaUIStatus(int code, String message, Throwable throwable) {
+ public PHPUIStatus(int code, String message, Throwable throwable) {
super(IStatus.ERROR, PHPeclipsePlugin.getPluginId(), code, message, throwable);
}
- public JavaUIStatus(int code, String message) {
+ public PHPUIStatus(int code, String message) {
this(code, message, null);
}
- public JavaUIStatus(int code) {
+ public PHPUIStatus(int code) {
this(code, ""); //$NON-NLS-1$
}
}
--- /dev/null
+package net.sourceforge.phpdt.internal.ui;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.graphics.Image;
+
+public class PHPUiImages {
+
+ protected static final String NAME_PREFIX = "net.sourceforge.phpdt.internal.ui.";
+ protected static final int NAME_PREFIX_LENGTH = NAME_PREFIX.length();
+
+ protected static URL iconBaseURL;
+
+ static {
+ String pathSuffix = "icons/";
+ try {
+ iconBaseURL = new URL(PHPeclipsePlugin.getDefault().getDescriptor().getInstallURL(), pathSuffix);
+ } catch (MalformedURLException e) {
+ PHPeclipsePlugin.log(e);
+ }
+ }
+
+ protected static final ImageRegistry IMAGE_REGISTRY = new ImageRegistry();
+
+ protected static final String OBJ_PREFIX = "obj16";
+ protected static final String OVR_PREFIX = "ovr16";
+ protected static final String CTOOL_PREFIX = "ctool16";
+
+ public static final String IMG_CLASS = NAME_PREFIX + "class_obj.gif";
+ public static final String IMG_FUN = NAME_PREFIX + "fun_obj.gif";
+ public static final String IMG_OBJS_ERROR = NAME_PREFIX + "error_obj.gif";
+ public static final String IMG_OBJS_WARNING = NAME_PREFIX + "warning_obj.gif";
+ public static final String IMG_OBJS_INFO = NAME_PREFIX + "info_obj.gif";
+ public static final String IMG_CTOOLS_PHP_PAGE = NAME_PREFIX + "php_page.gif";
+ public static final String IMG_CTOOLS_PHP = NAME_PREFIX + "php.gif";
+
+ public static final ImageDescriptor DESC_CLASS = createManaged(OBJ_PREFIX, IMG_CLASS);
+ public static final ImageDescriptor DESC_FUN = createManaged(OBJ_PREFIX, IMG_FUN);
+ public static final ImageDescriptor DESC_OBJS_ERROR = createManaged(OBJ_PREFIX, IMG_OBJS_ERROR);
+ public static final ImageDescriptor DESC_OBJS_WARNING = createManaged(OBJ_PREFIX, IMG_OBJS_WARNING);
+ public static final ImageDescriptor DESC_OBJS_INFO = createManaged(OBJ_PREFIX, IMG_OBJS_INFO);
+ public static final ImageDescriptor DESC_CTOOL_PHP_PAGE = createManaged(CTOOL_PREFIX, IMG_CTOOLS_PHP_PAGE);
+ public static final ImageDescriptor DESC_CTOOL_PHP = createManaged(CTOOL_PREFIX, IMG_CTOOLS_PHP);
+
+ /**
+ * Returns the image managed under the given key in this registry.
+ *
+ * @param key the image's key
+ * @return the image managed under the given key
+ */
+ public static Image get(String key) {
+ return IMAGE_REGISTRY.get(key);
+ }
+
+ /**
+ * Sets the three image descriptors for enabled, disabled, and hovered to an action. The actions
+ * are retrieved from the *tool16 folders.
+ */
+ public static void setToolImageDescriptors(IAction action, String iconName) {
+ setImageDescriptors(action, "tool16", iconName);
+ }
+
+ /**
+ * Sets the three image descriptors for enabled, disabled, and hovered to an action. The actions
+ * are retrieved from the *lcl16 folders.
+ */
+ public static void setLocalImageDescriptors(IAction action, String iconName) {
+ setImageDescriptors(action, "lcl16", iconName);
+ }
+
+ public static ImageRegistry getImageRegistry() {
+ return IMAGE_REGISTRY;
+ }
+
+ //---- Helper methods to access icons on the file system --------------------------------------
+
+ protected static void setImageDescriptors(IAction action, String type, String relPath) {
+
+ try {
+ ImageDescriptor id = ImageDescriptor.createFromURL(makeIconFileURL("d" + type, relPath));
+ if (id != null)
+ action.setDisabledImageDescriptor(id);
+ } catch (MalformedURLException e) {}
+
+ try {
+ ImageDescriptor id = ImageDescriptor.createFromURL(makeIconFileURL("c" + type, relPath));
+ if (id != null)
+ action.setHoverImageDescriptor(id);
+ } catch (MalformedURLException e) {}
+
+ action.setImageDescriptor(create("e" + type, relPath));
+ }
+
+ protected static ImageDescriptor createManaged(String prefix, String name) {
+ try {
+ ImageDescriptor result = ImageDescriptor.createFromURL(makeIconFileURL(prefix, name.substring(NAME_PREFIX_LENGTH)));
+ IMAGE_REGISTRY.put(name, result);
+ return result;
+ } catch (MalformedURLException e) {
+ return ImageDescriptor.getMissingImageDescriptor();
+ }
+ }
+
+ protected static ImageDescriptor create(String prefix, String name) {
+ try {
+ return ImageDescriptor.createFromURL(makeIconFileURL(prefix, name));
+ } catch (MalformedURLException e) {
+ return ImageDescriptor.getMissingImageDescriptor();
+ }
+ }
+
+ protected static URL makeIconFileURL(String prefix, String name) throws MalformedURLException {
+ if (iconBaseURL == null)
+ throw new MalformedURLException();
+
+ StringBuffer buffer = new StringBuffer(prefix);
+ buffer.append('/');
+ buffer.append(name);
+ return new URL(iconBaseURL, buffer.toString());
+ }
+}
\ No newline at end of file
--- /dev/null
+package net.sourceforge.phpdt.internal.ui.dialog;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+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.Text;
+import net.sourceforge.phpdt.internal.ui.util.FilteredList;
+
+/**
+ * An abstract class to select elements out of a list of elements.
+ */
+public abstract class AbstractElementListSelectionDialog extends SelectionStatusDialog {
+
+ private ILabelProvider fRenderer;
+ private boolean fIgnoreCase= true;
+ private boolean fIsMultipleSelection= false;
+ private boolean fMatchEmptyString= true;
+ private boolean fAllowDuplicates= true;
+
+ private Label fMessage;
+
+ protected FilteredList fFilteredList;
+ private Text fFilterText;
+
+ private ISelectionValidator fValidator;
+ private String fFilter= null;
+
+ private String fEmptyListMessage= ""; //$NON-NLS-1$
+ private String fEmptySelectionMessage= ""; //$NON-NLS-1$
+
+ private int fWidth= 60;
+ private int fHeight= 18;
+
+ private Object[] fSelection= new Object[0];
+
+ /**
+ * Constructs a list selection dialog.
+ * @param renderer The label renderer used
+ * @param ignoreCase Decides if the match string ignores lower/upppr case
+ * @param multipleSelection Allow multiple selection
+ */
+ protected AbstractElementListSelectionDialog(Shell parent, ILabelProvider renderer)
+ {
+ super(parent);
+ fRenderer= renderer;
+
+ int shellStyle= getShellStyle();
+ setShellStyle(shellStyle | SWT.MAX | SWT.RESIZE);
+ }
+
+ /**
+ * Handles default selection (double click).
+ * By default, the OK button is pressed.
+ */
+ protected void handleDefaultSelected() {
+ if (validateCurrentSelection())
+ buttonPressed(IDialogConstants.OK_ID);
+ }
+
+ /**
+ * Specifies if sorting, filtering and folding is case sensitive.
+ */
+ public void setIgnoreCase(boolean ignoreCase) {
+ fIgnoreCase= ignoreCase;
+ }
+
+ /**
+ * Returns if sorting, filtering and folding is case sensitive.
+ */
+ public boolean isCaseIgnored() {
+ return fIgnoreCase;
+ }
+
+ /**
+ * Specifies whether everything or nothing should be filtered on
+ * empty filter string.
+ */
+ public void setMatchEmptyString(boolean matchEmptyString) {
+ fMatchEmptyString= matchEmptyString;
+ }
+
+ /**
+ * Specifies if multiple selection is allowed.
+ */
+ public void setMultipleSelection(boolean multipleSelection) {
+ fIsMultipleSelection= multipleSelection;
+ }
+
+ /**
+ * Specifies whether duplicate entries are displayed or not.
+ */
+ public void setAllowDuplicates(boolean allowDuplicates) {
+ fAllowDuplicates= allowDuplicates;
+ }
+
+ /**
+ * Sets the list size in unit of characters.
+ * @param width the width of the list.
+ * @param height the height of the list.
+ */
+ public void setSize(int width, int height) {
+ fWidth= width;
+ fHeight= height;
+ }
+
+ /**
+ * Sets the message to be displayed if the list is empty.
+ * @param message the message to be displayed.
+ */
+ public void setEmptyListMessage(String message) {
+ fEmptyListMessage= message;
+ }
+
+ /**
+ * Sets the message to be displayed if the selection is empty.
+ * @param message the message to be displayed.
+ */
+ public void setEmptySelectionMessage(String message) {
+ fEmptySelectionMessage= message;
+ }
+
+ /**
+ * Sets an optional validator to check if the selection is valid.
+ * The validator is invoked whenever the selection changes.
+ * @param validator the validator to validate the selection.
+ */
+ public void setValidator(ISelectionValidator validator) {
+ fValidator= validator;
+ }
+
+ /**
+ * Sets the elements of the list (widget).
+ * To be called within open().
+ * @param elements the elements of the list.
+ */
+ protected void setListElements(Object[] elements) {
+ Assert.isNotNull(fFilteredList);
+ fFilteredList.setElements(elements);
+ }
+
+ /**
+ * Sets the filter pattern.
+ * @param filter the filter pattern.
+ */
+ public void setFilter(String filter) {
+ if (fFilterText == null)
+ fFilter= filter;
+ else
+ fFilterText.setText(filter);
+ }
+
+ /**
+ * Returns the current filter pattern.
+ * @return returns the current filter pattern or <code>null<code> if filter was not set.
+ */
+ public String getFilter() {
+ if (fFilteredList == null)
+ return fFilter;
+ else
+ return fFilteredList.getFilter();
+ }
+
+ /**
+ * Returns the indices referring the current selection.
+ * To be called within open().
+ * @return returns the indices of the current selection.
+ */
+ protected int[] getSelectionIndices() {
+ Assert.isNotNull(fFilteredList);
+ return fFilteredList.getSelectionIndices();
+ }
+
+ /**
+ * Returns an index referring the first current selection.
+ * To be called within open().
+ * @return returns the indices of the current selection.
+ */
+ protected int getSelectionIndex() {
+ Assert.isNotNull(fFilteredList);
+ return fFilteredList.getSelectionIndex();
+ }
+
+ /**
+ * Sets the selection referenced by an array of elements.
+ * To be called within open().
+ * @param selection the indices of the selection.
+ */
+ protected void setSelection(Object[] selection) {
+ Assert.isNotNull(fFilteredList);
+ fFilteredList.setSelection(selection);
+ }
+
+ /**
+ * Returns an array of the currently selected elements.
+ * To be called within or after open().
+ * @return returns an array of the currently selected elements.
+ */
+ protected Object[] getSelectedElements() {
+ Assert.isNotNull(fFilteredList);
+ return fFilteredList.getSelection();
+ }
+
+ /**
+ * Returns all elements which are folded together to one entry in the list.
+ * @param index the index selecting the entry in the list.
+ * @return returns an array of elements folded together.
+ */
+ public Object[] getFoldedElements(int index) {
+ Assert.isNotNull(fFilteredList);
+ return fFilteredList.getFoldedElements(index);
+ }
+
+ /**
+ * Creates the message text widget and sets layout data.
+ * @param composite the parent composite of the message area.
+ */
+ protected Label createMessageArea(Composite composite) {
+ Label label= super.createMessageArea(composite);
+
+ GridData data= new GridData();
+ data.grabExcessVerticalSpace= false;
+ data.grabExcessHorizontalSpace= true;
+ data.horizontalAlignment= GridData.FILL;
+ data.verticalAlignment= GridData.BEGINNING;
+ label.setLayoutData(data);
+
+ fMessage= label;
+
+ return label;
+ }
+
+ /**
+ * Handles a selection changed event.
+ * By default, the current selection is validated.
+ */
+ protected void handleSelectionChanged() {
+ validateCurrentSelection();
+ }
+
+ /**
+ * Validates the current selection and updates the status line
+ * accordingly.
+ */
+ protected boolean validateCurrentSelection() {
+ Assert.isNotNull(fFilteredList);
+
+ IStatus status;
+ Object[] elements= getSelectedElements();
+
+ if (elements.length > 0) {
+ if (fValidator != null) {
+ status= fValidator.validate(elements);
+ } else {
+ status= new StatusInfo();
+ }
+ } else {
+ if (fFilteredList.isEmpty()) {
+ status= new StatusInfo(IStatus.ERROR, fEmptyListMessage);
+ } else {
+ status= new StatusInfo(IStatus.ERROR, fEmptySelectionMessage);
+ }
+ }
+
+ updateStatus(status);
+
+ return status.isOK();
+ }
+
+ /*
+ * @see Dialog#cancelPressed
+ */
+ protected void cancelPressed() {
+ setResult(null);
+ super.cancelPressed();
+ }
+
+ /**
+ * Creates a filtered list.
+ * @param parent the parent composite.
+ * @return returns the filtered list widget.
+ */
+ protected FilteredList createFilteredList(Composite parent) {
+ int flags= SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL |
+ (fIsMultipleSelection ? SWT.MULTI : SWT.SINGLE);
+
+ FilteredList list= new FilteredList(parent, flags, fRenderer,
+ fIgnoreCase, fAllowDuplicates, fMatchEmptyString);
+
+ GridData data= new GridData();
+ data.widthHint= convertWidthInCharsToPixels(fWidth);
+ data.heightHint= convertHeightInCharsToPixels(fHeight);
+ data.grabExcessVerticalSpace= true;
+ data.grabExcessHorizontalSpace= true;
+ data.horizontalAlignment= GridData.FILL;
+ data.verticalAlignment= GridData.FILL;
+ list.setLayoutData(data);
+
+ list.setFilter((fFilter == null ? "" : fFilter)); //$NON-NLS-1$
+
+ list.addSelectionListener(new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {
+ handleDefaultSelected();
+ }
+ public void widgetSelected(SelectionEvent e) {
+ handleWidgetSelected();
+ }
+ });
+
+ fFilteredList= list;
+
+ return list;
+ }
+
+ // 3515
+ private void handleWidgetSelected() {
+ Object[] newSelection= fFilteredList.getSelection();
+
+ if (newSelection.length != fSelection.length) {
+ fSelection= newSelection;
+ handleSelectionChanged();
+ } else {
+ for (int i= 0; i != newSelection.length; i++) {
+ if (!newSelection[i].equals(fSelection[i])) {
+ fSelection= newSelection;
+ handleSelectionChanged();
+ break;
+ }
+ }
+ }
+ }
+
+ protected Text createFilterText(Composite parent) {
+ Text text= new Text(parent, SWT.BORDER);
+
+ GridData data= new GridData();
+ data.grabExcessVerticalSpace= false;
+ data.grabExcessHorizontalSpace= true;
+ data.horizontalAlignment= GridData.FILL;
+ data.verticalAlignment= GridData.BEGINNING;
+ text.setLayoutData(data);
+
+ text.setText((fFilter == null ? "" : fFilter)); //$NON-NLS-1$
+
+ Listener listener= new Listener() {
+ public void handleEvent(Event e) {
+ fFilteredList.setFilter(fFilterText.getText());
+ }
+ };
+ text.addListener(SWT.Modify, listener);
+
+ text.addKeyListener(new KeyListener() {
+ public void keyPressed(KeyEvent e) {
+ if (e.keyCode == SWT.ARROW_DOWN)
+ fFilteredList.setFocus();
+ }
+
+ public void keyReleased(KeyEvent e) {}
+ });
+
+ fFilterText= text;
+
+ return text;
+ }
+
+ /*
+ * @see Window#open()
+ */
+ public int open() {
+ BusyIndicator.showWhile(null, new Runnable() {
+ public void run() {
+ access$superOpen();
+ }
+ });
+ return getReturnCode();
+ }
+
+ private void access$superOpen() {
+ super.open();
+ }
+
+ /*
+ * @see Window#create(Shell)
+ */
+ public void create() {
+ super.create();
+
+ Assert.isNotNull(fFilteredList);
+
+ if (fFilteredList.isEmpty()) {
+ handleEmptyList();
+ } else {
+ validateCurrentSelection();
+ fFilterText.selectAll();
+ fFilterText.setFocus();
+ }
+ }
+
+ /**
+ * Handles empty list by disabling widgets.
+ */
+ protected void handleEmptyList() {
+ fMessage.setEnabled(false);
+ fFilterText.setEnabled(false);
+ fFilteredList.setEnabled(false);
+ }
+
+}
--- /dev/null
+package net.sourceforge.phpdt.internal.ui.dialog;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTreeViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+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.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Tree;
+import net.sourceforge.phpdt.internal.ui.viewsupport.ContainerCheckedTreeViewer;
+
+/**
+ * A class to select elements out of a tree structure.
+ */
+public class CheckedTreeSelectionDialog extends SelectionStatusDialog {
+
+ private CheckboxTreeViewer fViewer;
+
+ private ILabelProvider fLabelProvider;
+ private ITreeContentProvider fContentProvider;
+
+ private ISelectionValidator fValidator = null;
+ private ViewerSorter fSorter;
+ private String fEmptyListMessage = "No entries available";
+
+ private IStatus fCurrStatus = new StatusInfo();
+ private List fFilters;
+ private Object fInput;
+ private boolean fIsEmpty;
+
+ private int fWidth = 60;
+ private int fHeight = 18;
+
+ private boolean fContainerMode;
+ private Object[] fExpandedElements;
+
+ /**
+ * Constructs an instance of <code>ElementTreeSelectionDialog</code>.
+ * @param labelProvider the label provider to render the entries
+ * @param contentProvider the content provider to evaluate the tree structure
+ */
+ public CheckedTreeSelectionDialog(Shell parent, ILabelProvider labelProvider, ITreeContentProvider contentProvider) {
+ super(parent);
+
+ fLabelProvider = labelProvider;
+ fContentProvider = contentProvider;
+
+ setResult(new ArrayList(0));
+ setStatusLineAboveButtons(true);
+
+ fContainerMode = false;
+ fExpandedElements = null;
+
+ int shellStyle = getShellStyle();
+ setShellStyle(shellStyle | SWT.MAX | SWT.RESIZE);
+ }
+
+ /**
+ * If set, the checked /gray state of containers (inner nodes) is derived from the checked state of its
+ * leaf nodes.
+ * @param containerMode The containerMode to set
+ */
+ public void setContainerMode(boolean containerMode) {
+ fContainerMode = containerMode;
+ }
+
+ /**
+ * Sets the initial selection.
+ * Convenience method.
+ * @param selection the initial selection.
+ */
+ public void setInitialSelection(Object selection) {
+ setInitialSelections(new Object[] { selection });
+ }
+
+ /**
+ * Sets the message to be displayed if the list is empty.
+ * @param message the message to be displayed.
+ */
+ public void setEmptyListMessage(String message) {
+ fEmptyListMessage = message;
+ }
+
+ /**
+ * Sets the sorter used by the tree viewer.
+ */
+ public void setSorter(ViewerSorter sorter) {
+ fSorter = sorter;
+ }
+
+ /**
+ * Adds a filter to the tree viewer.
+ * @param filter a filter.
+ */
+ public void addFilter(ViewerFilter filter) {
+ if (fFilters == null)
+ fFilters = new ArrayList(4);
+
+ fFilters.add(filter);
+ }
+
+ /**
+ * Sets an optional validator to check if the selection is valid.
+ * The validator is invoked whenever the selection changes.
+ * @param validator the validator to validate the selection.
+ */
+ public void setValidator(ISelectionValidator validator) {
+ fValidator = validator;
+ }
+
+ /**
+ * Sets the tree input.
+ * @param input the tree input.
+ */
+ public void setInput(Object input) {
+ fInput = input;
+ }
+
+ /**
+ * Expands the tree
+ */
+ public void setExpandedElements(Object[] elements) {
+ fExpandedElements = elements;
+ }
+
+ /**
+ * Sets the size of the tree in unit of characters.
+ * @param width the width of the tree.
+ * @param height the height of the tree.
+ */
+ public void setSize(int width, int height) {
+ fWidth = width;
+ fHeight = height;
+ }
+
+ protected void updateOKStatus() {
+ if (!fIsEmpty) {
+ if (fValidator != null) {
+ fCurrStatus = fValidator.validate(fViewer.getCheckedElements());
+ updateStatus(fCurrStatus);
+ } else if (!fCurrStatus.isOK()) {
+ fCurrStatus = new StatusInfo();
+ }
+ } else {
+ fCurrStatus = new StatusInfo(IStatus.ERROR, fEmptyListMessage);
+ }
+ updateStatus(fCurrStatus);
+ }
+
+ /*
+ * @see Window#open()
+ */
+ public int open() {
+ fIsEmpty = evaluateIfTreeEmpty(fInput);
+ BusyIndicator.showWhile(null, new Runnable() {
+ public void run() {
+ access$superOpen();
+ }
+ });
+
+ return getReturnCode();
+ }
+
+ private void access$superOpen() {
+ super.open();
+ }
+
+ /**
+ * Handles cancel button pressed event.
+ */
+ protected void cancelPressed() {
+ setResult(null);
+ super.cancelPressed();
+ }
+
+ /*
+ * @see SelectionStatusDialog#computeResult()
+ */
+ protected void computeResult() {
+ setResult(Arrays.asList(fViewer.getCheckedElements()));
+ }
+
+ /*
+ * @see Window#create()
+ */
+ public void create() {
+ super.create();
+
+ List initialSelections = getInitialSelections();
+ if (initialSelections != null) {
+ fViewer.setCheckedElements(initialSelections.toArray());
+ }
+
+ if (fExpandedElements != null) {
+ fViewer.setExpandedElements(fExpandedElements);
+ }
+
+ updateOKStatus();
+ }
+
+ /*
+ * @see Dialog#createDialogArea(Composite)
+ */
+ protected Control createDialogArea(Composite parent) {
+ Composite composite = (Composite) super.createDialogArea(parent);
+
+ Label messageLabel = createMessageArea(composite);
+ Control treeWidget = createTreeViewer(composite);
+ Control buttonComposite = createSelectionButtons(composite);
+
+ GridData data = new GridData(GridData.FILL_BOTH);
+ data.widthHint = convertWidthInCharsToPixels(fWidth);
+ data.heightHint = convertHeightInCharsToPixels(fHeight);
+ treeWidget.setLayoutData(data);
+
+ if (fIsEmpty) {
+ messageLabel.setEnabled(false);
+ treeWidget.setEnabled(false);
+ buttonComposite.setEnabled(false);
+ }
+
+ return composite;
+ }
+
+ private Tree createTreeViewer(Composite parent) {
+ if (fContainerMode) {
+ fViewer = new ContainerCheckedTreeViewer(parent, SWT.BORDER);
+ } else {
+ fViewer = new CheckboxTreeViewer(parent, SWT.BORDER);
+ }
+
+ fViewer.setContentProvider(fContentProvider);
+ fViewer.setLabelProvider(fLabelProvider);
+ fViewer.addCheckStateListener(new ICheckStateListener() {
+ public void checkStateChanged(CheckStateChangedEvent event) {
+ updateOKStatus();
+ }
+ });
+
+ fViewer.setSorter(fSorter);
+ if (fFilters != null) {
+ for (int i = 0; i != fFilters.size(); i++)
+ fViewer.addFilter((ViewerFilter) fFilters.get(i));
+ }
+
+ fViewer.setInput(fInput);
+
+ return fViewer.getTree();
+ }
+
+ /**
+ * Add the selection and deselection buttons to the dialog.
+ * @param composite org.eclipse.swt.widgets.Composite
+ */
+ private Composite createSelectionButtons(Composite composite) {
+
+ Composite buttonComposite = new Composite(composite, SWT.RIGHT);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 2;
+ buttonComposite.setLayout(layout);
+ GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.GRAB_HORIZONTAL);
+ data.grabExcessHorizontalSpace = true;
+ composite.setData(data);
+
+ Button selectButton = createButton(buttonComposite, IDialogConstants.SELECT_ALL_ID, "Select &All", false);
+
+ SelectionListener listener = new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ fViewer.setCheckedElements(fContentProvider.getElements(fInput));
+ updateOKStatus();
+ }
+ };
+ selectButton.addSelectionListener(listener);
+
+ Button deselectButton = createButton(buttonComposite, IDialogConstants.DESELECT_ALL_ID, "&Deselect All", false);
+
+ listener = new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ fViewer.setCheckedElements(new Object[0]);
+ updateOKStatus();
+ }
+ };
+ deselectButton.addSelectionListener(listener);
+ return buttonComposite;
+ }
+
+ private boolean evaluateIfTreeEmpty(Object input) {
+ Object[] elements = fContentProvider.getElements(input);
+ if (elements.length > 0) {
+ if (fFilters != null) {
+ for (int i = 0; i < fFilters.size(); i++) {
+ ViewerFilter curr = (ViewerFilter) fFilters.get(i);
+ elements = curr.filter(fViewer, input, elements);
+ }
+ }
+ }
+ return elements.length == 0;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package net.sourceforge.phpdt.internal.ui.dialog;
+
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+
+import java.util.List;
+import java.util.Arrays;
+import org.eclipse.jface.viewers.ILabelProvider;
+
+/**
+ * A class to select elements out of a list of elements.
+ */
+public class ElementListSelectionDialog extends AbstractElementListSelectionDialog {
+
+ private Object[] fElements;
+
+ /**
+ * Creates a list selection dialog.
+ * @param parent the parent widget.
+ * @param renderer the label renderer.
+ */
+ public ElementListSelectionDialog(Shell parent, ILabelProvider renderer) {
+ super(parent, renderer);
+ }
+
+ /**
+ * Sets the elements of the list.
+ * @param elements the elements of the list.
+ */
+ public void setElements(Object[] elements) {
+ fElements= elements;
+ }
+
+ /*
+ * @see SelectionStatusDialog#computeResult()
+ */
+ protected void computeResult() {
+ setResult(Arrays.asList(getSelectedElements()));
+ }
+
+ /*
+ * @see Dialog#createDialogArea(Composite)
+ */
+ protected Control createDialogArea(Composite parent) {
+ Composite contents= (Composite) super.createDialogArea(parent);
+
+ createMessageArea(contents);
+ createFilterText(contents);
+ createFilteredList(contents);
+
+ setListElements(fElements);
+
+ List initialSelections= getInitialSelections();
+ if (initialSelections != null)
+ setSelection(initialSelections.toArray());
+
+ return contents;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package net.sourceforge.phpdt.internal.ui.dialog;
+
+import org.eclipse.core.runtime.IStatus;
+
+public interface ISelectionValidator {
+
+ IStatus validate(Object[] selection);
+
+}
\ No newline at end of file
--- /dev/null
+package net.sourceforge.phpdt.internal.ui.dialog;
+
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CLabel;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A message line displaying a status.
+ */
+public class MessageLine extends CLabel {
+
+ private static final RGB ERROR_BACKGROUND_RGB = new RGB(230, 226, 221);
+
+ private Color fNormalMsgAreaBackground;
+ private Color fErrorMsgAreaBackground;
+
+ /**
+ * Creates a new message line as a child of the given parent.
+ */
+ public MessageLine(Composite parent) {
+ this(parent, SWT.LEFT);
+ }
+
+ /**
+ * Creates a new message line as a child of the parent and with the given SWT stylebits.
+ */
+ public MessageLine(Composite parent, int style) {
+ super(parent, style);
+ fNormalMsgAreaBackground= getBackground();
+ fErrorMsgAreaBackground= null;
+ }
+
+
+ private Image findImage(IStatus status) {
+ if (status.isOK()) {
+ return null;
+ } else if (status.matches(IStatus.ERROR)) {
+ return PHPUiImages.get(PHPUiImages.IMG_OBJS_ERROR);
+ } else if (status.matches(IStatus.WARNING)) {
+ return PHPUiImages.get(PHPUiImages.IMG_OBJS_WARNING);
+ } else if (status.matches(IStatus.INFO)) {
+ return PHPUiImages.get(PHPUiImages.IMG_OBJS_INFO);
+ }
+ return null;
+ }
+
+ /**
+ * Sets the message and image to the given status.
+ * <code>null</code> is a valid argument and will set the empty text and no image
+ */
+ public void setErrorStatus(IStatus status) {
+ if (status != null) {
+ String message= status.getMessage();
+ if (message != null && message.length() > 0) {
+ setText(message);
+ setImage(findImage(status));
+ if (fErrorMsgAreaBackground == null) {
+ fErrorMsgAreaBackground= new Color(getDisplay(), ERROR_BACKGROUND_RGB);
+ }
+ setBackground(fErrorMsgAreaBackground);
+ return;
+ }
+ }
+ setText("");
+ setImage(null);
+ setBackground(fNormalMsgAreaBackground);
+ }
+
+ /*
+ * @see Widget#dispose()
+ */
+ public void dispose() {
+ if (fErrorMsgAreaBackground != null) {
+ fErrorMsgAreaBackground.dispose();
+ fErrorMsgAreaBackground= null;
+ }
+ super.dispose();
+ }
+}
\ No newline at end of file
--- /dev/null
+package net.sourceforge.phpdt.internal.ui.dialog;
+
+import java.util.Arrays;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+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.Shell;
+import org.eclipse.ui.dialogs.SelectionDialog;
+
+
+/**
+ * An abstract base class for dialogs with a status bar and ok/cancel buttons.
+ * The status message must be passed over as StatusInfo object and can be
+ * an error, warning or ok. The OK button is enabled or disabled depending
+ * on the status.
+ */
+public abstract class SelectionStatusDialog extends SelectionDialog {
+
+ private MessageLine fStatusLine;
+ private IStatus fLastStatus;
+ private Image fImage;
+ private boolean fStatusLineAboveButtons= false;
+
+ /**
+ * Creates an instance of a <code>SelectionStatusDialog</code>.
+ */
+ public SelectionStatusDialog(Shell parent) {
+ super(parent);
+ }
+
+ /**
+ * Controls whether status line appears to the left of the buttons (default)
+ * or above them.
+ *
+ * @param aboveButtons if <code>true</code> status line is placed above buttons; if
+ * <code>false</code> to the right
+ */
+ public void setStatusLineAboveButtons(boolean aboveButtons) {
+ fStatusLineAboveButtons= aboveButtons;
+ }
+
+ /**
+ * Sets the image for this dialog.
+ * @param image the image.
+ */
+ public void setImage(Image image) {
+ fImage= image;
+ }
+
+ /**
+ * Returns the first element from the list of results. Returns <code>null</code>
+ * if no element has been selected.
+ *
+ * @return the first result element if one exists. Otherwise <code>null</code> is
+ * returned.
+ */
+ public Object getFirstResult() {
+ Object[] result= getResult();
+ if (result == null || result.length == 0)
+ return null;
+ return result[0];
+ }
+
+ /**
+ * Sets a result element at the given position.
+ */
+ protected void setResult(int position, Object element) {
+ Object[] result= getResult();
+ result[position]= element;
+ setResult(Arrays.asList(result));
+ }
+
+ /**
+ * Compute the result and return it.
+ */
+ protected abstract void computeResult();
+
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ if (fImage != null)
+ shell.setImage(fImage);
+ }
+
+ /**
+ * Update the dialog's status line to reflect the given status. It is safe to call
+ * this method before the dialog has been opened.
+ */
+ protected void updateStatus(IStatus status) {
+ fLastStatus= status;
+ if (fStatusLine != null && !fStatusLine.isDisposed()) {
+ updateButtonsEnableState(status);
+ fStatusLine.setErrorStatus(status);
+ }
+ }
+
+ /**
+ * Update the status of the ok button to reflect the given status. Subclasses
+ * may override this method to update additional buttons.
+ */
+ protected void updateButtonsEnableState(IStatus status) {
+ Button okButton= getOkButton();
+ if (okButton != null && !okButton.isDisposed())
+ okButton.setEnabled(!status.matches(IStatus.ERROR));
+ }
+
+ protected void okPressed() {
+ computeResult();
+ super.okPressed();
+ }
+
+ public void create() {
+ super.create();
+ if (fLastStatus != null)
+ updateStatus(fLastStatus);
+ }
+
+ protected Control createButtonBar(Composite parent) {
+ Composite composite= new Composite(parent, SWT.NULL);
+ GridLayout layout= new GridLayout();
+ if (fStatusLineAboveButtons) {
+ layout.marginWidth= 5;
+ } else {
+ layout.numColumns= 2;
+ }
+ layout.marginHeight= 0; layout.marginWidth= 0;
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ fStatusLine= new MessageLine(composite);
+ fStatusLine.setAlignment(SWT.LEFT);
+ fStatusLine.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ fStatusLine.setErrorStatus(null);
+
+ GridData gd= new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalIndent= convertWidthInCharsToPixels(1);
+ fStatusLine.setLayoutData(gd);
+
+ super.createButtonBar(composite);
+ return composite;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package net.sourceforge.phpdt.internal.ui.dialog;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+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.Shell;
+
+/**
+ * An abstract base class for dialogs with a status bar and ok/cancel buttons.
+ * The status message must be passed over as StatusInfo object and can be
+ * an error, warning or ok. The OK button is enabled or disabled depending
+ * on the status.
+ */
+public abstract class StatusDialog extends Dialog {
+
+ private Button fOkButton;
+ private MessageLine fStatusLine;
+ private IStatus fLastStatus;
+ private String fTitle;
+ private Image fImage;
+
+ private boolean fStatusLineAboveButtons;
+
+ /**
+ * Creates an instane of a status dialog.
+ */
+ public StatusDialog(Shell parent) {
+ super(parent);
+ fStatusLineAboveButtons= false;
+ }
+
+ /**
+ * Specifies whether status line appears to the left of the buttons (default)
+ * or above them.
+ *
+ * @param aboveButtons if <code>true</code> status line is placed above buttons; if
+ * <code>false</code> to the right
+ */
+ public void setStatusLineAboveButtons(boolean aboveButtons) {
+ fStatusLineAboveButtons= aboveButtons;
+ }
+
+ /**
+ * Update the dialog's status line to reflect the given status.
+ * It is save to call this method before the dialog has been opened.
+ */
+ protected void updateStatus(IStatus status) {
+ fLastStatus= status;
+ if (fStatusLine != null && !fStatusLine.isDisposed()) {
+ updateButtonsEnableState(status);
+ fStatusLine.setErrorStatus(status);
+ }
+ }
+
+ /**
+ * Returns the last status.
+ */
+ public IStatus getStatus() {
+ return fLastStatus;
+ }
+
+ /**
+ * Updates the status of the ok button to reflect the given status.
+ * Subclasses may override this method to update additional buttons.
+ * @param status the status.
+ */
+ protected void updateButtonsEnableState(IStatus status) {
+ if (fOkButton != null && !fOkButton.isDisposed())
+ fOkButton.setEnabled(!status.matches(IStatus.ERROR));
+ }
+
+ /*
+ * @see Window#create(Shell)
+ */
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ if (fTitle != null)
+ shell.setText(fTitle);
+ }
+
+ /*
+ * @see Window#create()
+ */
+ public void create() {
+ super.create();
+ if (fLastStatus != null) {
+ // policy: dialogs are not allowed to come up with an error message
+ if (fLastStatus.matches(IStatus.ERROR)) {
+ StatusInfo status= new StatusInfo();
+ status.setError(""); //$NON-NLS-1$
+ fLastStatus= status;
+ }
+ updateStatus(fLastStatus);
+ }
+ }
+
+ /*
+ * @see Dialog#createButtonsForButtonBar(Composite)
+ */
+ protected void createButtonsForButtonBar(Composite parent) {
+ fOkButton= createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
+ createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
+ }
+
+ /*
+ * @see Dialog#createButtonBar(Composite)
+ */
+ protected Control createButtonBar(Composite parent) {
+ Composite composite= new Composite(parent, SWT.NULL);
+ GridLayout layout= new GridLayout();
+ layout.numColumns= 1;
+ layout.marginHeight= 0;
+ layout.marginWidth= convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ fStatusLine= new MessageLine(composite);
+ fStatusLine.setAlignment(SWT.LEFT);
+ fStatusLine.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ fStatusLine.setErrorStatus(null); //$NON-NLS-1$
+
+ super.createButtonBar(composite);
+ return composite;
+ }
+
+ /**
+ * Sets the title for this dialog.
+ * @param title the title.
+ */
+ public void setTitle(String title) {
+ fTitle= title != null ? title : ""; //$NON-NLS-1$
+ Shell shell= getShell();
+ if ((shell != null) && !shell.isDisposed())
+ shell.setText(fTitle);
+ }
+
+ /**
+ * Sets the image for this dialog.
+ * @param image the image.
+ */
+ public void setImage(Image image) {
+ fImage= image;
+ Shell shell= getShell();
+ if ((shell != null) && !shell.isDisposed())
+ shell.setImage(fImage);
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package net.sourceforge.phpdt.internal.ui.dialog;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.util.Assert;
+
+/**
+ * A settable IStatus.
+ * Can be an error, warning, info or ok. For error, info and warning states,
+ * a message describes the problem.
+ */
+public class StatusInfo implements IStatus {
+
+ private String fStatusMessage;
+ private int fSeverity;
+
+ /**
+ * Creates a status set to OK (no message)
+ */
+ public StatusInfo() {
+ this(OK, null);
+ }
+
+ /**
+ * Creates a status .
+ * @param severity The status severity: ERROR, WARNING, INFO and OK.
+ * @param message The message of the status. Applies only for ERROR,
+ * WARNING and INFO.
+ */
+ public StatusInfo(int severity, String message) {
+ fStatusMessage = message;
+ fSeverity = severity;
+ }
+
+ /**
+ * Returns if the status' severity is OK.
+ */
+ public boolean isOK() {
+ return fSeverity == IStatus.OK;
+ }
+
+ /**
+ * Returns if the status' severity is WARNING.
+ */
+ public boolean isWarning() {
+ return fSeverity == IStatus.WARNING;
+ }
+
+ /**
+ * Returns if the status' severity is INFO.
+ */
+ public boolean isInfo() {
+ return fSeverity == IStatus.INFO;
+ }
+
+ /**
+ * Returns if the status' severity is ERROR.
+ */
+ public boolean isError() {
+ return fSeverity == IStatus.ERROR;
+ }
+
+ /**
+ * @see IStatus#getMessage
+ */
+ public String getMessage() {
+ return fStatusMessage;
+ }
+
+ /**
+ * Sets the status to ERROR.
+ * @param The error message (can be empty, but not null)
+ */
+ public void setError(String errorMessage) {
+ Assert.isNotNull(errorMessage);
+ fStatusMessage = errorMessage;
+ fSeverity = IStatus.ERROR;
+ }
+
+ /**
+ * Sets the status to WARNING.
+ * @param The warning message (can be empty, but not null)
+ */
+ public void setWarning(String warningMessage) {
+ Assert.isNotNull(warningMessage);
+ fStatusMessage = warningMessage;
+ fSeverity = IStatus.WARNING;
+ }
+
+ /**
+ * Sets the status to INFO.
+ * @param The info message (can be empty, but not null)
+ */
+ public void setInfo(String infoMessage) {
+ Assert.isNotNull(infoMessage);
+ fStatusMessage = infoMessage;
+ fSeverity = IStatus.INFO;
+ }
+
+ /**
+ * Sets the status to OK.
+ */
+ public void setOK() {
+ fStatusMessage = null;
+ fSeverity = IStatus.OK;
+ }
+
+ /*
+ * @see IStatus#matches(int)
+ */
+ public boolean matches(int severityMask) {
+ return (fSeverity & severityMask) != 0;
+ }
+
+ /**
+ * Returns always <code>false</code>.
+ * @see IStatus#isMultiStatus()
+ */
+ public boolean isMultiStatus() {
+ return false;
+ }
+
+ /*
+ * @see IStatus#getSeverity()
+ */
+ public int getSeverity() {
+ return fSeverity;
+ }
+
+ /*
+ * @see IStatus#getPlugin()
+ */
+ public String getPlugin() {
+ return PHPeclipsePlugin.PLUGIN_ID;
+ }
+
+ /**
+ * Returns always <code>null</code>.
+ * @see IStatus#getException()
+ */
+ public Throwable getException() {
+ return null;
+ }
+
+ /**
+ * Returns always the error severity.
+ * @see IStatus#getCode()
+ */
+ public int getCode() {
+ return fSeverity;
+ }
+
+ /**
+ * Returns always <code>null</code>.
+ * @see IStatus#getChildren()
+ */
+ public IStatus[] getChildren() {
+ return new IStatus[0];
+ }
+
+}
\ No newline at end of file
import net.sourceforge.phpdt.internal.corext.template.ContextType;
import net.sourceforge.phpdt.internal.corext.template.ContextTypeRegistry;
//import org.eclipse.jdt.internal.ui.JavaPlugin;
-import net.sourceforge.phpdt.internal.ui.JavaUIMessages;
+import net.sourceforge.phpdt.internal.ui.PHPUIMessages;
//import org.eclipse.jdt.internal.ui.text.JavaCodeReader;
import net.sourceforge.phpdt.internal.ui.text.template.TemplateEngine;
*/
public String getErrorMessage() {
// if (fNumberOfComputedResults == 0)
- return JavaUIMessages.getString("JavaEditor.codeassist.noCompletions"); //$NON-NLS-1$
+ return PHPUIMessages.getString("JavaEditor.codeassist.noCompletions"); //$NON-NLS-1$
// return fCollector.getErrorMessage();
}
--- /dev/null
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui.text.template;
+
+import java.util.ArrayList;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+
+//import org.eclipse.jdt.core.ICompilationUnit;
+//import org.eclipse.jdt.core.JavaModelException;
+
+//import org.eclipse.jdt.internal.corext.Assert;
+import net.sourceforge.phpdt.internal.corext.template.ContextType;
+import net.sourceforge.phpdt.internal.corext.template.Template;
+import net.sourceforge.phpdt.internal.corext.template.Templates;
+import net.sourceforge.phpdt.internal.corext.template.java.CompilationUnitContext;
+import net.sourceforge.phpdt.internal.corext.template.java.CompilationUnitContextType;
+//import org.eclipse.jdt.internal.ui.JavaPluginImages;
+import net.sourceforge.phpdt.internal.ui.text.java.IJavaCompletionProposal;
+//import org.eclipse.jdt.internal.ui.text.link.LinkedPositionManager;
+
+public class IdentifierEngine {
+
+ /** The context type. */
+ private ContextType fContextType;
+ /** The result proposals. */
+ private ArrayList fProposals= new ArrayList();
+
+ /**
+ * Creates the template engine for a particular context type.
+ * See <code>TemplateContext</code> for supported context types.
+ */
+ public IdentifierEngine(ContextType contextType) {
+ // Assert.isNotNull(contextType);
+ fContextType= contextType;
+ }
+
+ /**
+ * Empties the collector.
+ *
+ * @param viewer the text viewer
+ * @param unit the compilation unit (may be <code>null</code>)
+ */
+ public void reset() {
+ fProposals.clear();
+ }
+
+ /**
+ * Returns the array of matching templates.
+ */
+ public IJavaCompletionProposal[] getResults() {
+ return (IJavaCompletionProposal[]) fProposals.toArray(new IJavaCompletionProposal[fProposals.size()]);
+ }
+
+ /**
+ * Inspects the context of the compilation unit around <code>completionPosition</code>
+ * and feeds the collector with proposals.
+ * @param viewer the text viewer
+ * @param completionPosition the context position in the document of the text viewer
+ * @param compilationUnit the compilation unit (may be <code>null</code>)
+ */
+ public void complete(ITextViewer viewer, int completionPosition, Object[] identifiers)
+ //,ICompilationUnit compilationUnit)
+ //hrows JavaModelException
+ {
+ IDocument document= viewer.getDocument();
+
+ // prohibit recursion
+// if (LinkedPositionManager.hasActiveManager(document))
+// return;
+
+ if (!(fContextType instanceof CompilationUnitContextType))
+ return;
+
+ ((CompilationUnitContextType) fContextType).setContextParameters(document, completionPosition);//mpilationUnit);
+ CompilationUnitContext context= (CompilationUnitContext) fContextType.createContext();
+ int start= context.getStart();
+ int end= context.getEnd();
+ IRegion region= new Region(start, end - start);
+
+// Template[] templates= Templates.getInstance().getTemplates();
+ String identifier = null;
+ for (int i= 0; i != identifiers.length; i++) {
+ identifier = (String) identifiers[i];
+ if (context.canEvaluate(identifier)) {
+ fProposals.add(new IdentifierProposal(identifier, context, region, viewer)); //luginImages.get(JavaPluginImages.IMG_OBJS_TEMPLATE)));
+ }
+ }
+ }
+
+}
+
--- /dev/null
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui.text.template;
+
+import net.sourceforge.phpdt.internal.corext.template.Template;
+import net.sourceforge.phpdt.internal.corext.template.TemplateBuffer;
+import net.sourceforge.phpdt.internal.corext.template.TemplateContext;
+import net.sourceforge.phpdt.internal.corext.template.TemplateMessages;
+import net.sourceforge.phpdt.internal.corext.template.TemplatePosition;
+import net.sourceforge.phpdt.internal.corext.template.java.CompilationUnitContext;
+import net.sourceforge.phpdt.internal.corext.template.java.JavaTemplateMessages;
+import net.sourceforge.phpdt.internal.ui.text.java.IJavaCompletionProposal;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import org.eclipse.core.runtime.CoreException;
+import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionManager;
+import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Shell;
+//import org.eclipse.jdt.internal.ui.text.link.LinkedPositionManager;
+//import org.eclipse.jdt.internal.ui.text.link.LinkedPositionUI;
+//import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
+
+/**
+ * A PHP identifier proposal.
+ */
+public class IdentifierProposal implements IJavaCompletionProposal {
+
+ private final String fTemplate;
+ private final TemplateContext fContext;
+ private final ITextViewer fViewer;
+ // private final Image fImage;
+ private final IRegion fRegion;
+
+ //private TemplateBuffer fTemplateBuffer;
+ private String fOldText;
+ private IRegion fSelectedRegion; // initialized by apply()
+
+ /**
+ * Creates a template proposal with a template and its context.
+ * @param template the template
+ * @param context the context in which the template was requested.
+ * @param image the icon of the proposal.
+ */
+ public IdentifierProposal(String template, TemplateContext context, IRegion region, ITextViewer viewer) { //, Image image) {
+ // Assert.isNotNull(template);
+ // Assert.isNotNull(context);
+ // Assert.isNotNull(region);
+ // Assert.isNotNull(viewer);
+
+ fTemplate = template;
+ fContext = context;
+ fViewer = viewer;
+ // fImage= image;
+ fRegion = region;
+ }
+
+ /*
+ * @see ICompletionProposal#apply(IDocument)
+ */
+ public void apply(IDocument document) {
+ try {
+ // if (fTemplateBuffer == null)
+ // fTemplateBuffer= fContext.evaluate(fTemplate);
+
+ int start = fRegion.getOffset();
+ int end = fRegion.getOffset() + fRegion.getLength();
+
+ // insert template string
+ // String templateString = fTemplate; // fTemplateBuffer.getString();
+ document.replace(start, end - start, fTemplate);
+
+ // translate positions
+ LinkedPositionManager manager = new LinkedPositionManager(document);
+ // TemplatePosition[] variables= fTemplateBuffer.getVariables();
+ // for (int i= 0; i != variables.length; i++) {
+ // TemplatePosition variable= variables[i];
+ //
+ // if (variable.isResolved())
+ // continue;
+ //
+ // int[] offsets= variable.getOffsets();
+ // int length= variable.getLength();
+ //
+ // for (int j= 0; j != offsets.length; j++)
+ // manager.addPosition(offsets[j] + start, length);
+ // }
+
+ LinkedPositionUI editor = new LinkedPositionUI(fViewer, manager);
+ editor.setFinalCaretOffset(fTemplate.length()+start);
+ // editor.setFinalCaretOffset(getCaretOffset(fTemplateBuffer) + start);
+ editor.enter();
+
+ fSelectedRegion = editor.getSelectedRegion();
+
+ } catch (BadLocationException e) {
+ PHPeclipsePlugin.log(e);
+ openErrorDialog(e);
+
+ }
+ // catch (CoreException e) {
+ // handleException(e);
+ // }
+ }
+
+// private static int getCaretOffset(TemplateBuffer buffer) {
+// TemplatePosition[] variables = buffer.getVariables();
+// for (int i = 0; i != variables.length; i++) {
+// TemplatePosition variable = variables[i];
+//
+// if (variable.getName().equals(JavaTemplateMessages.getString("GlobalVariables.variable.name.cursor"))) //$NON-NLS-1$
+// return variable.getOffsets()[0];
+// }
+//
+// return buffer.getString().length();
+// }
+
+ /*
+ * @see ICompletionProposal#getSelection(IDocument)
+ */
+ public Point getSelection(IDocument document) {
+ return new Point(fSelectedRegion.getOffset(), fSelectedRegion.getLength());
+ // return null;
+ }
+
+ /*
+ * @see ICompletionProposal#getAdditionalProposalInfo()
+ */
+ public String getAdditionalProposalInfo() {
+ // try {
+ // if (fTemplateBuffer == null)
+ // fTemplateBuffer= fContext.evaluate(fTemplate);
+
+ return textToHTML(fTemplate); // fTemplateBuffer.getString());
+
+ // } catch (CoreException e) {
+ // handleException(e);
+ // return null;
+ // }
+ }
+
+ /*
+ * @see ICompletionProposal#getDisplayString()
+ */
+ public String getDisplayString() {
+ return fTemplate + TemplateMessages.getString("TemplateProposal.delimiter") + fTemplate; // $NON-NLS-1$ //$NON-NLS-1$
+ // return fTemplate.getName() + TemplateMessages.getString("TemplateProposal.delimiter") + fTemplate.getDescription(); // $NON-NLS-1$ //$NON-NLS-1$
+ }
+
+ /*
+ * @see ICompletionProposal#getImage()
+ */
+ public Image getImage() {
+ // return fImage;
+ return null;
+ }
+
+ /*
+ * @see ICompletionProposal#getContextInformation()
+ */
+ public IContextInformation getContextInformation() {
+ return null;
+ }
+
+ private static String textToHTML(String string) {
+ StringBuffer buffer = new StringBuffer(string.length());
+ buffer.append("<pre>"); //$NON-NLS-1$
+
+ for (int i = 0; i != string.length(); i++) {
+ char ch = string.charAt(i);
+
+ switch (ch) {
+ case '&' :
+ buffer.append("&"); //$NON-NLS-1$
+ break;
+
+ case '<' :
+ buffer.append("<"); //$NON-NLS-1$
+ break;
+
+ case '>' :
+ buffer.append(">"); //$NON-NLS-1$
+ break;
+
+ case '\t' :
+ buffer.append(" "); //$NON-NLS-1$
+ break;
+
+ case '\n' :
+ buffer.append("<br>"); //$NON-NLS-1$
+ break;
+
+ default :
+ buffer.append(ch);
+ break;
+ }
+ }
+
+ buffer.append("</pre>"); //$NON-NLS-1$
+ return buffer.toString();
+ }
+
+ private void openErrorDialog(BadLocationException e) {
+ Shell shell = fViewer.getTextWidget().getShell();
+ MessageDialog.openError(shell, TemplateMessages.getString("TemplateEvaluator.error.title"), e.getMessage()); //$NON-NLS-1$
+ }
+
+ private void handleException(CoreException e) {
+ Shell shell = fViewer.getTextWidget().getShell();
+ PHPeclipsePlugin.log(e);
+ // ExceptionHandler.handle(e, shell, TemplateMessages.getString("TemplateEvaluator.error.title"), null); //$NON-NLS-1$
+ }
+
+ /*
+ * @see IJavaCompletionProposal#getRelevance()
+ */
+ public int getRelevance() {
+
+ if (fContext instanceof CompilationUnitContext) {
+ CompilationUnitContext context = (CompilationUnitContext) fContext;
+ switch (context.getCharacterBeforeStart()) {
+ // high relevance after whitespace
+ case ' ' :
+ case '\r' :
+ case '\n' :
+ case '\t' :
+ return 90;
+
+ default :
+ return 0;
+ }
+ } else {
+ return 90;
+ }
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package net.sourceforge.phpdt.internal.ui.util;
+
+import java.io.File;
+
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.DirectoryDialog;
+
+public class DirectorySelector extends ResourceSelector {
+
+ public DirectorySelector(Composite parent) {
+ super(parent);
+ }
+
+ protected void handleBrowseSelected() {
+ DirectoryDialog dialog = new DirectoryDialog(getShell());
+ dialog.setMessage(browseDialogMessage);
+ String currentWorkingDir = textField.getText();
+ if (!currentWorkingDir.trim().equals("")) {
+ File path = new File(currentWorkingDir);
+ if (path.exists()) {
+ dialog.setFilterPath(currentWorkingDir);
+ }
+ }
+
+ String selectedDirectory = dialog.open();
+ if (selectedDirectory != null) {
+ textField.setText(selectedDirectory);
+ }
+ }
+
+ protected String validateResourceSelection() {
+ String directory = textField.getText();
+ File directoryFile = new File(directory);
+ if (directoryFile.exists() && directoryFile.isDirectory())
+ return directory;
+ return EMPTY_STRING;
+ }
+}
--- /dev/null
+package net.sourceforge.phpdt.internal.ui.util;
+
+import java.io.StringWriter;
+import java.lang.reflect.InvocationTargetException;
+
+import net.sourceforge.phpdt.internal.ui.PHPUIMessages;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Shell;
+
+
+public class ExceptionHandler {
+ private static ExceptionHandler fgInstance= new ExceptionHandler();
+
+ public static void log(Throwable t, String message) {
+ PHPeclipsePlugin.getDefault().getLog().log(new Status(IStatus.ERROR, PHPeclipsePlugin.PLUGIN_ID,
+ IStatus.ERROR, message, t));
+ }
+
+ public static void handle(CoreException e, String title, String message) {
+ handle(e, PHPeclipsePlugin.getActiveWorkbenchShell(), title, message);
+ }
+
+ public static void handle(CoreException e, Shell parent, String title, String message) {
+ fgInstance.perform(e, parent, title, message);
+ }
+
+ public static void handle(InvocationTargetException e, String title, String message) {
+ handle(e, PHPeclipsePlugin.getActiveWorkbenchShell(), title, message);
+ }
+
+ public static void handle(InvocationTargetException e, Shell parent, String title, String message) {
+ fgInstance.perform(e, parent, title, message);
+ }
+
+ protected void perform(CoreException e, Shell shell, String title, String message) {
+ PHPeclipsePlugin.log(e);
+ IStatus status= e.getStatus();
+ if (status != null) {
+ ErrorDialog.openError(shell, title, message, status);
+ } else {
+ displayMessageDialog(e, e.getMessage(), shell, title, message);
+ }
+ }
+
+ protected void perform(InvocationTargetException e, Shell shell, String title, String message) {
+ Throwable target= e.getTargetException();
+ if (target instanceof CoreException) {
+ perform((CoreException)target, shell, title, message);
+ } else {
+ PHPeclipsePlugin.log(e);
+ if (e.getMessage() != null && e.getMessage().length() > 0) {
+ displayMessageDialog(e, e.getMessage(), shell, title, message);
+ } else {
+ displayMessageDialog(e, target.getMessage(), shell, title, message);
+ }
+ }
+ }
+
+ private void displayMessageDialog(Throwable t, String exceptionMessage, Shell shell, String title, String message) {
+ StringWriter msg= new StringWriter();
+ if (message != null) {
+ msg.write(message);
+ msg.write("\n\n");
+ }
+ if (exceptionMessage == null || exceptionMessage.length() == 0)
+ msg.write(PHPUIMessages.getString("ExceptionDialog.seeErrorLogMessage"));
+ else
+ msg.write(exceptionMessage);
+ MessageDialog.openError(shell, title, msg.toString());
+ }
+}
\ No newline at end of file
--- /dev/null
+package net.sourceforge.phpdt.internal.ui.util;
+
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Vector;
+
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+
+/**
+ * A composite widget which holds a list of elements for user selection.
+ * The elements are sorted alphabetically.
+ * Optionally, the elements can be filtered and duplicate entries can
+ * be hidden (folding).
+ */
+public class FilteredList extends Composite {
+
+ public interface FilterMatcher {
+ /**
+ * Sets the filter.
+ *
+ * @param pattern the filter pattern.
+ * @param ignoreCase a flag indicating whether pattern matching is case insensitive or not.
+ * @param ignoreWildCards a flag indicating whether wildcard characters are interpreted or not.
+ */
+ void setFilter(String pattern, boolean ignoreCase, boolean ignoreWildCards);
+
+ /**
+ * Returns <code>true</code> if the object matches the pattern, <code>false</code> otherwise.
+ * <code>setFilter()</code> must have been called at least once prior to a call to this method.
+ */
+ boolean match(Object element);
+ }
+
+ private class DefaultFilterMatcher implements FilterMatcher {
+ private StringMatcher fMatcher;
+
+ public void setFilter(String pattern, boolean ignoreCase, boolean ignoreWildCards) {
+ fMatcher= new StringMatcher(pattern + '*', ignoreCase, ignoreWildCards);
+ }
+
+ public boolean match(Object element) {
+ return fMatcher.match(fRenderer.getText(element));
+ }
+ }
+
+ private Table fList;
+ private ILabelProvider fRenderer;
+ private boolean fMatchEmtpyString= true;
+ private boolean fIgnoreCase;
+ private boolean fAllowDuplicates;
+ private String fFilter= ""; //$NON-NLS-1$
+ private TwoArrayQuickSorter fSorter;
+
+ private Object[] fElements= new Object[0];
+ private Label[] fLabels;
+ private Vector fImages= new Vector();
+
+ private int[] fFoldedIndices;
+ private int fFoldedCount;
+
+ private int[] fFilteredIndices;
+ private int fFilteredCount;
+
+ private FilterMatcher fFilterMatcher= new DefaultFilterMatcher();
+ private Comparator fComparator;
+
+ private static class Label {
+ public final String string;
+ public final Image image;
+
+ public Label(String string, Image image) {
+ this.string= string;
+ this.image= image;
+ }
+
+ public boolean equals(Label label) {
+ if (label == null)
+ return false;
+
+ return
+ string.equals(label.string) &&
+ image.equals(label.image);
+ }
+ }
+
+ private final class LabelComparator implements Comparator {
+ private boolean fIgnoreCase;
+
+ LabelComparator(boolean ignoreCase) {
+ fIgnoreCase= ignoreCase;
+ }
+
+ public int compare(Object left, Object right) {
+ Label leftLabel= (Label) left;
+ Label rightLabel= (Label) right;
+
+ int value;
+
+ if (fComparator == null) {
+ value= fIgnoreCase
+ ? leftLabel.string.compareToIgnoreCase(rightLabel.string)
+ : leftLabel.string.compareTo(rightLabel.string);
+ } else {
+ value= fComparator.compare(leftLabel.string, rightLabel.string);
+ }
+
+ if (value != 0)
+ return value;
+
+ // images are allowed to be null
+ if (leftLabel.image == null) {
+ return (rightLabel.image == null) ? 0 : -1;
+ } else if (rightLabel.image == null) {
+ return +1;
+ } else {
+ return
+ fImages.indexOf(leftLabel.image) -
+ fImages.indexOf(rightLabel.image);
+ }
+ }
+
+ }
+
+ /**
+ * Constructs a new instance of a filtered list.
+ * @param parent the parent composite.
+ * @param style the widget style.
+ * @param renderer the label renderer.
+ * @param ignoreCase specifies whether sorting and folding is case sensitive.
+ * @param allowDuplicates specifies whether folding of duplicates is desired.
+ * @param matchEmptyString specifies whether empty filter strings should filter everything or nothing.
+ */
+ public FilteredList(Composite parent, int style, ILabelProvider renderer,
+ boolean ignoreCase, boolean allowDuplicates, boolean matchEmptyString)
+ {
+ super(parent, SWT.NONE);
+
+ GridLayout layout= new GridLayout();
+ layout.marginHeight= 0;
+ layout.marginWidth= 0;
+ setLayout(layout);
+
+ fList= new Table(this, style);
+ fList.setLayoutData(new GridData(GridData.FILL_BOTH));
+ fList.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ fRenderer.dispose();
+ }
+ });
+
+ fRenderer= renderer;
+ fIgnoreCase= ignoreCase;
+ fSorter= new TwoArrayQuickSorter(new LabelComparator(ignoreCase));
+ fAllowDuplicates= allowDuplicates;
+ fMatchEmtpyString= matchEmptyString;
+ }
+
+ /**
+ * Sets the list of elements.
+ * @param elements the elements to be shown in the list.
+ */
+ public void setElements(Object[] elements) {
+ if (elements == null) {
+ fElements= new Object[0];
+ } else {
+ // copy list for sorting
+ fElements= new Object[elements.length];
+ System.arraycopy(elements, 0, fElements, 0, elements.length);
+ }
+
+ int length= fElements.length;
+
+ // fill labels
+ fLabels= new Label[length];
+ Set imageSet= new HashSet();
+ for (int i= 0; i != length; i++) {
+ String text= fRenderer.getText(fElements[i]);
+ Image image= fRenderer.getImage(fElements[i]);
+
+ fLabels[i]= new Label(text, image);
+ imageSet.add(image);
+ }
+ fImages.clear();
+ fImages.addAll(imageSet);
+
+ fSorter.sort(fLabels, fElements);
+
+ fFilteredIndices= new int[length];
+ fFilteredCount= filter();
+
+ fFoldedIndices= new int[length];
+ fFoldedCount= fold();
+
+ updateList();
+ }
+
+ /**
+ * Tests if the list (before folding and filtering) is empty.
+ * @return returns <code>true</code> if the list is empty, <code>false</code> otherwise.
+ */
+ public boolean isEmpty() {
+ return (fElements == null) || (fElements.length == 0);
+ }
+
+ /**
+ * Sets the filter matcher.
+ */
+ public void setFilterMatcher(FilterMatcher filterMatcher) {
+ Assert.isNotNull(filterMatcher);
+ fFilterMatcher= filterMatcher;
+ }
+
+ /**
+ * Sets a custom comparator for sorting the list.
+ */
+ public void setComparator(Comparator comparator) {
+ Assert.isNotNull(comparator);
+ fComparator= comparator;
+ }
+
+ /**
+ * Adds a selection listener to the list.
+ * @param listener the selection listener to be added.
+ */
+ public void addSelectionListener(SelectionListener listener) {
+ fList.addSelectionListener(listener);
+ }
+
+ /**
+ * Removes a selection listener from the list.
+ * @param listener the selection listener to be removed.
+ */
+ public void removeSelectionListener(SelectionListener listener) {
+ fList.removeSelectionListener(listener);
+ }
+
+ /**
+ * Sets the selection of the list.
+ * @param selection an array of indices specifying the selection.
+ */
+ public void setSelection(int[] selection) {
+ fList.setSelection(selection);
+ }
+
+ /**
+ * Returns the selection of the list.
+ * @return returns an array of indices specifying the current selection.
+ */
+ public int[] getSelectionIndices() {
+ return fList.getSelectionIndices();
+ }
+
+ /**
+ * Returns the selection of the list.
+ * This is a convenience function for <code>getSelectionIndices()</code>.
+ * @return returns the index of the selection, -1 for no selection.
+ */
+ public int getSelectionIndex() {
+ return fList.getSelectionIndex();
+ }
+
+ /**
+ * Sets the selection of the list.
+ * @param elements the array of elements to be selected.
+ */
+ public void setSelection(Object[] elements) {
+ if ((elements == null) || (fElements == null))
+ return;
+
+ // fill indices
+ int[] indices= new int[elements.length];
+ for (int i= 0; i != elements.length; i++) {
+ int j;
+ for (j= 0; j != fFoldedCount; j++) {
+ int max= (j == fFoldedCount - 1)
+ ? fFilteredCount
+ : fFoldedIndices[j + 1];
+
+ int l;
+ for (l= fFoldedIndices[j]; l != max; l++) {
+ // found matching element?
+ if (fElements[fFilteredIndices[l]].equals(elements[i])) {
+ indices[i]= j;
+ break;
+ }
+ }
+
+ if (l != max)
+ break;
+ }
+
+ // not found
+ if (j == fFoldedCount)
+ indices[i] = 0;
+ }
+
+ fList.setSelection(indices);
+ }
+
+ /**
+ * Returns an array of the selected elements. The type of the elements
+ * returned in the list are the same as the ones passed with
+ * <code>setElements</code>. The array does not contain the rendered strings.
+ * @return returns the array of selected elements.
+ */
+ public Object[] getSelection() {
+ if (fList.isDisposed() || (fList.getSelectionCount() == 0))
+ return new Object[0];
+
+ int[] indices= fList.getSelectionIndices();
+ Object[] elements= new Object[indices.length];
+
+ for (int i= 0; i != indices.length; i++)
+ elements[i]= fElements[fFilteredIndices[fFoldedIndices[indices[i]]]];
+
+ return elements;
+ }
+
+ /**
+ * Sets the filter pattern. Current only prefix filter patterns are supported.
+ * @param filter the filter pattern.
+ */
+ public void setFilter(String filter) {
+ fFilter= (filter == null) ? "" : filter; //$NON-NLS-1$
+
+ fFilteredCount= filter();
+ fFoldedCount= fold();
+ updateList();
+ }
+
+ /**
+ * Returns the filter pattern.
+ * @return returns the filter pattern.
+ */
+ public String getFilter() {
+ return fFilter;
+ }
+
+ /**
+ * Returns all elements which are folded together to one entry in the list.
+ * @param index the index selecting the entry in the list.
+ * @return returns an array of elements folded together, <code>null</code> if index is out of range.
+ */
+ public Object[] getFoldedElements(int index) {
+ if ((index < 0) || (index >= fFoldedCount))
+ return null;
+
+ int start= fFoldedIndices[index];
+ int count= (index == fFoldedCount - 1)
+ ? fFilteredCount - start
+ : fFoldedIndices[index + 1] - start;
+
+ Object[] elements= new Object[count];
+ for (int i= 0; i != count; i++)
+ elements[i]= fElements[fFilteredIndices[start + i]];
+
+ return elements;
+ }
+
+ /*
+ * Folds duplicate entries. Two elements are considered as a pair of
+ * duplicates if they coiincide in the rendered string and image.
+ * @return returns the number of elements after folding.
+ */
+ private int fold() {
+ if (fAllowDuplicates) {
+ for (int i= 0; i != fFilteredCount; i++)
+ fFoldedIndices[i]= i; // identity mapping
+
+ return fFilteredCount;
+
+ } else {
+ int k= 0;
+ Label last= null;
+ for (int i= 0; i != fFilteredCount; i++) {
+ int j= fFilteredIndices[i];
+
+ Label current= fLabels[j];
+ if (! current.equals(last)) {
+ fFoldedIndices[k]= i;
+ k++;
+ last= current;
+ }
+ }
+ return k;
+ }
+ }
+
+ /*
+ * Filters the list with the filter pattern.
+ * @return returns the number of elements after filtering.
+ */
+ private int filter() {
+ if (((fFilter == null) || (fFilter.length() == 0)) && !fMatchEmtpyString)
+ return 0;
+
+ fFilterMatcher.setFilter(fFilter.trim(), fIgnoreCase, false);
+
+ int k= 0;
+ for (int i= 0; i != fElements.length; i++) {
+ if (fFilterMatcher.match(fElements[i]))
+ fFilteredIndices[k++]= i;
+ }
+
+ return k;
+ }
+
+ /*
+ * Updates the list widget.
+ */
+ private void updateList() {
+ if (fList.isDisposed())
+ return;
+
+ fList.setRedraw(false);
+
+ // resize table
+ int itemCount= fList.getItemCount();
+ if (fFoldedCount < itemCount)
+ fList.remove(0, itemCount - fFoldedCount - 1);
+ else if (fFoldedCount > itemCount)
+ for (int i= 0; i != fFoldedCount - itemCount; i++)
+ new TableItem(fList, SWT.NONE);
+
+ // fill table
+ TableItem[] items= fList.getItems();
+ for (int i= 0; i != fFoldedCount; i++) {
+ TableItem item= items[i];
+ Label label= fLabels[fFilteredIndices[fFoldedIndices[i]]];
+
+ item.setText(label.string);
+ item.setImage(label.image);
+ }
+
+ // select first item if any
+ if (fList.getItemCount() > 0)
+ fList.setSelection(0);
+
+ fList.setRedraw(true);
+ fList.notifyListeners(SWT.Selection, new Event());
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package net.sourceforge.phpdt.internal.ui.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceVisitor;
+import org.eclipse.core.runtime.CoreException;
+
+public class PHPElementVisitor implements IResourceVisitor {
+ protected List phpFiles = new ArrayList();
+
+ public PHPElementVisitor() {
+ super();
+ }
+
+ public boolean visit(IResource resource) throws CoreException {
+ switch (resource.getType()) {
+ case IResource.PROJECT :
+ return true;
+
+ case IResource.FOLDER :
+ return true;
+
+ case IResource.FILE :
+ IFile fileResource = (IFile) resource;
+ if ( "php".equals(fileResource.getFileExtension()) ||
+ "php3".equals(fileResource.getFileExtension()) ||
+ "php4".equals(fileResource.getFileExtension()) ) {
+ phpFiles.add(fileResource);
+ return true;
+ }
+
+ default :
+ return false;
+ }
+ }
+
+ public Object[] getCollectedPHPFiles() {
+ return phpFiles.toArray();
+ }
+}
--- /dev/null
+package net.sourceforge.phpdt.internal.ui.util;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+import net.sourceforge.phpdt.internal.ui.dialog.ElementListSelectionDialog;
+
+public class PHPFileSelector extends ResourceSelector {
+ protected PHPProjectSelector phpProjectSelector;
+
+ public PHPFileSelector(Composite parent, PHPProjectSelector aProjectSelector) {
+ super(parent);
+ Assert.isNotNull(aProjectSelector);
+ phpProjectSelector = aProjectSelector;
+
+ browseDialogTitle = "File Selection";
+ }
+
+ protected Object[] getPHPFiles() {
+ IProject phpProject = phpProjectSelector.getSelection();
+ if (phpProject == null)
+ return new Object[0];
+
+ PHPElementVisitor visitor = new PHPElementVisitor();
+ try {
+ phpProject.accept(visitor);
+ } catch(CoreException e) {
+ PHPeclipsePlugin.log(e);
+ }
+ return visitor.getCollectedPHPFiles();
+ }
+
+ public IFile getSelection() {
+ String fileName = getSelectionText();
+ if (fileName != null && !fileName.equals("")) {
+ IPath filePath = new Path(fileName);
+ IProject project = phpProjectSelector.getSelection();
+ if (project != null && project.exists(filePath))
+ return project.getFile(filePath);
+ }
+
+ return null;
+ }
+
+ protected void handleBrowseSelected() {
+ ElementListSelectionDialog dialog = new ElementListSelectionDialog(getShell(), new WorkbenchLabelProvider());
+ dialog.setTitle(browseDialogTitle);
+ dialog.setMessage(browseDialogMessage);
+ dialog.setElements(getPHPFiles());
+
+ if (dialog.open() == dialog.OK) {
+ textField.setText(((IResource) dialog.getFirstResult()).getProjectRelativePath().toString());
+ }
+ }
+
+ protected String validateResourceSelection() {
+ IFile selection = getSelection();
+ return selection == null ? EMPTY_STRING : selection.getProjectRelativePath().toString();
+ }
+}
--- /dev/null
+package net.sourceforge.phpdt.internal.ui.util;
+
+import net.sourceforge.phpeclipse.PHPCore;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+import net.sourceforge.phpdt.internal.ui.dialog.ElementListSelectionDialog;
+
+public class PHPProjectSelector extends ResourceSelector {
+
+ public PHPProjectSelector(Composite parent) {
+ super(parent);
+
+ browseDialogTitle = "Project Selection";
+ }
+
+ public IProject getSelection() {
+ String projectName = getSelectionText();
+ if (projectName != null && !projectName.equals(""))
+ return PHPeclipsePlugin.getWorkspace().getRoot().getProject(projectName);
+
+ return null;
+ }
+
+ protected void handleBrowseSelected() {
+ ElementListSelectionDialog dialog = new ElementListSelectionDialog(getShell(), new WorkbenchLabelProvider());
+ dialog.setTitle(browseDialogTitle);
+ dialog.setMessage(browseDialogMessage);
+ dialog.setElements(PHPCore.getPHPProjects());
+
+ if (dialog.open() == dialog.OK) {
+ textField.setText(((IProject) dialog.getFirstResult()).getName());
+ }
+ }
+
+ protected String validateResourceSelection() {
+ IProject project = getSelection();
+ return project == null ? EMPTY_STRING : project.getName();
+ }
+}
\ No newline at end of file
--- /dev/null
+package net.sourceforge.phpdt.internal.ui.util;
+
+import org.eclipse.swt.graphics.FontMetrics;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.widgets.Control;
+
+import org.eclipse.jface.dialogs.Dialog;
+
+public class PixelConverter {
+
+ private FontMetrics fFontMetrics;
+
+ public PixelConverter(Control control) {
+ GC gc = new GC(control);
+ gc.setFont(control.getFont());
+ fFontMetrics= gc.getFontMetrics();
+ gc.dispose();
+ }
+
+ private FontMetrics fgFontMetrics;
+
+ /**
+ * @see org.eclipse.jface.dialogs.DialogPage#convertHeightInCharsToPixels(int)
+ */
+ public int convertHeightInCharsToPixels(int chars) {
+ return Dialog.convertHeightInCharsToPixels(fFontMetrics, chars);
+ }
+
+ /**
+ * @see org.eclipse.jface.dialogs.DialogPage#convertHorizontalDLUsToPixels(int)
+ */
+ public int convertHorizontalDLUsToPixels(int dlus) {
+ return Dialog.convertHorizontalDLUsToPixels(fFontMetrics, dlus);
+ }
+
+ /**
+ * @see org.eclipse.jface.dialogs.DialogPage#convertVerticalDLUsToPixels(int)
+ */
+ public int convertVerticalDLUsToPixels(int dlus) {
+ return Dialog.convertVerticalDLUsToPixels(fFontMetrics, dlus);
+ }
+
+ /**
+ * @see org.eclipse.jface.dialogs.DialogPage#convertWidthInCharsToPixels(int)
+ */
+ public int convertWidthInCharsToPixels(int chars) {
+ return Dialog.convertWidthInCharsToPixels(fFontMetrics, chars);
+ }
+
+}
--- /dev/null
+package net.sourceforge.phpdt.internal.ui.util;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+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.Shell;
+import org.eclipse.swt.widgets.Text;
+
+public abstract class ResourceSelector {
+ protected final static String EMPTY_STRING = "";
+ protected Composite composite;
+ protected Button browseButton;
+ protected Text textField;
+ protected String browseDialogMessage = EMPTY_STRING;
+ protected String browseDialogTitle = EMPTY_STRING;
+ protected String validatedSelectionText = EMPTY_STRING;
+
+ public ResourceSelector(Composite parent) {
+ composite = new Composite(parent, SWT.NONE);
+ GridLayout compositeLayout = new GridLayout();
+ compositeLayout.marginWidth = 0;
+ compositeLayout.marginHeight = 0;
+ compositeLayout.numColumns = 2;
+ composite.setLayout(compositeLayout);
+
+ textField = new Text(composite, SWT.SINGLE | SWT.BORDER);
+ textField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ textField.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ validatedSelectionText = validateResourceSelection();
+ }
+ });
+
+ browseButton = new Button(composite, SWT.PUSH);
+ browseButton.setText("Browse...");
+ browseButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ handleBrowseSelected();
+ }
+ });
+ }
+
+ protected abstract void handleBrowseSelected();
+ protected abstract String validateResourceSelection();
+
+ protected Shell getShell() {
+ return composite.getShell();
+ }
+
+ public void setLayoutData(Object layoutData) {
+ composite.setLayoutData(layoutData);
+ }
+
+ public void addModifyListener(ModifyListener aListener) {
+ textField.addModifyListener(aListener);
+ }
+
+ public void setBrowseDialogMessage(String aMessage) {
+ browseDialogMessage = aMessage;
+ }
+
+ public void setBrowseDialogTitle(String aTitle) {
+ browseDialogTitle = aTitle;
+ }
+
+ public void setEnabled(boolean enabled) {
+ composite.setEnabled(enabled);
+ textField.setEnabled(enabled);
+ browseButton.setEnabled(enabled);
+ }
+
+ public String getSelectionText() {
+ return textField.getText();
+ }
+
+ public String getValidatedSelectionText() {
+ return validatedSelectionText;
+ }
+
+ public void setSelectionText(String newText) {
+ textField.setText(newText);
+ }
+}
--- /dev/null
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui.util;
+
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.DragSource;
+import org.eclipse.swt.dnd.DropTarget;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Caret;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.ScrollBar;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Widget;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.util.Assert;
+
+/**
+ * Utility class to simplify access to some SWT resources.
+ */
+public class SWTUtil {
+
+ /**
+ * Returns the standard display to be used. The method first checks, if
+ * the thread calling this method has an associated disaply. If so, this
+ * display is returned. Otherwise the method returns the default display.
+ */
+ public static Display getStandardDisplay() {
+ Display display;
+ display= Display.getCurrent();
+ if (display == null)
+ display= Display.getDefault();
+ return display;
+ }
+
+ /**
+ * Returns the shell for the given widget. If the widget doesn't represent
+ * a SWT object that manage a shell, <code>null</code> is returned.
+ *
+ * @return the shell for the given widget
+ */
+ public static Shell getShell(Widget widget) {
+ if (widget instanceof Control)
+ return ((Control)widget).getShell();
+ if (widget instanceof Caret)
+ return ((Caret)widget).getParent().getShell();
+ if (widget instanceof DragSource)
+ return ((DragSource)widget).getControl().getShell();
+ if (widget instanceof DropTarget)
+ return ((DropTarget)widget).getControl().getShell();
+ if (widget instanceof Menu)
+ return ((Menu)widget).getParent().getShell();
+ if (widget instanceof ScrollBar)
+ return ((ScrollBar)widget).getParent().getShell();
+
+ return null;
+ }
+
+
+ /**
+ * Returns a width hint for a button control.
+ */
+ public static int getButtonWidthHint(Button button) {
+ PixelConverter converter= new PixelConverter(button);
+ int widthHint= converter.convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
+ return Math.max(widthHint, button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
+ }
+
+ /**
+ * Returns a height hint for a button control.
+ */
+ public static int getButtonHeigthHint(Button button) {
+ PixelConverter converter= new PixelConverter(button);
+ return converter.convertVerticalDLUsToPixels(IDialogConstants.BUTTON_HEIGHT);
+ }
+
+
+ /**
+ * Sets width and height hint for the button control.
+ * <b>Note:</b> This is a NOP if the button's layout data is not
+ * an instance of <code>GridData</code>.
+ *
+ * @param the button for which to set the dimension hint
+ */
+ public static void setButtonDimensionHint(Button button) {
+ Assert.isNotNull(button);
+ Object gd= button.getLayoutData();
+ if (gd instanceof GridData) {
+ ((GridData)gd).heightHint= getButtonHeigthHint(button);
+ ((GridData)gd).widthHint= getButtonWidthHint(button);
+ }
+ }
+
+
+}
\ No newline at end of file
--- /dev/null
+package net.sourceforge.phpdt.internal.ui.util;
+
+import java.util.*;
+
+
+/**
+ * A string pattern matcher, suppporting * and ? wildcards.
+ */
+public class StringMatcher {
+ protected String fPattern;
+ protected int fLength; // pattern length
+ protected boolean fIgnoreWildCards;
+ protected boolean fIgnoreCase;
+ protected boolean fHasLeadingStar;
+ protected boolean fHasTrailingStar;
+ protected String fSegments[]; //the given pattern is split into * separated segments
+
+ /* boundary value beyond which we don't need to search in the text */
+ protected int fBound= 0;
+
+
+ protected static final char fSingleWildCard= '\u0000';
+
+ public static class Position {
+ int start; //inclusive
+ int end; //exclusive
+ public Position(int start, int end) {
+ this.start= start;
+ this.end= end;
+ }
+ public int getStart() {
+ return start;
+ }
+ public int getEnd() {
+ return end;
+ }
+ }
+ /**
+ * StringMatcher constructor takes in a String object that is a simple
+ * pattern which may contain ‘*’ for 0 and many characters and
+ * ‘?’ for exactly one character.
+ *
+ * Literal '*' and '?' characters must be escaped in the pattern
+ * e.g., "\*" means literal "*", etc.
+ *
+ * Escaping any other character (including the escape character itself),
+ * just results in that character in the pattern.
+ * e.g., "\a" means "a" and "\\" means "\"
+ *
+ * If invoking the StringMatcher with string literals in Java, don't forget
+ * escape characters are represented by "\\".
+ *
+ * @param pattern the pattern to match text against
+ * @param ignoreCase if true, case is ignored
+ * @param ignoreWildCards if true, wild cards and their escape sequences are ignored
+ * (everything is taken literally).
+ */
+ public StringMatcher(String pattern, boolean ignoreCase, boolean ignoreWildCards) {
+ if (pattern == null)
+ throw new IllegalArgumentException();
+ fIgnoreCase= ignoreCase;
+ fIgnoreWildCards= ignoreWildCards;
+ fPattern= pattern;
+ fLength= pattern.length();
+
+ if (fIgnoreWildCards) {
+ parseNoWildCards();
+ } else {
+ parseWildCards();
+ }
+ }
+ /**
+ * Find the first occurrence of the pattern between <code>start</code)(inclusive)
+ * and <code>end</code>(exclusive).
+ * @param <code>text</code>, the String object to search in
+ * @param <code>start</code>, the starting index of the search range, inclusive
+ * @param <code>end</code>, the ending index of the search range, exclusive
+ * @return an <code>StringMatcher.Position</code> object that keeps the starting
+ * (inclusive) and ending positions (exclusive) of the first occurrence of the
+ * pattern in the specified range of the text; return null if not found or subtext
+ * is empty (start==end). A pair of zeros is returned if pattern is empty string
+ * Note that for pattern like "*abc*" with leading and trailing stars, position of "abc"
+ * is returned. For a pattern like"*??*" in text "abcdf", (1,3) is returned
+ */
+ public StringMatcher.Position find(String text, int start, int end) {
+ if (text == null)
+ throw new IllegalArgumentException();
+
+ int tlen= text.length();
+ if (start < 0)
+ start= 0;
+ if (end > tlen)
+ end= tlen;
+ if (end < 0 ||start >= end )
+ return null;
+ if (fLength == 0)
+ return new Position(start, start);
+ if (fIgnoreWildCards) {
+ int x= posIn(text, start, end);
+ if (x < 0)
+ return null;
+ return new Position(x, x+fLength);
+ }
+
+ int segCount= fSegments.length;
+ if (segCount == 0)//pattern contains only '*'(s)
+ return new Position (start, end);
+
+ int curPos= start;
+ int matchStart= -1;
+ int i;
+ for (i= 0; i < segCount && curPos < end; ++i) {
+ String current= fSegments[i];
+ int nextMatch= regExpPosIn(text, curPos, end, current);
+ if (nextMatch < 0 )
+ return null;
+ if(i == 0)
+ matchStart= nextMatch;
+ curPos= nextMatch + current.length();
+ }
+ if (i < segCount)
+ return null;
+ return new Position(matchStart, curPos);
+ }
+ /**
+ * match the given <code>text</code> with the pattern
+ * @return true if matched eitherwise false
+ * @param <code>text</code>, a String object
+ */
+ public boolean match(String text) {
+ return match(text, 0, text.length());
+ }
+ /**
+ * Given the starting (inclusive) and the ending (exclusive) positions in the
+ * <code>text</code>, determine if the given substring matches with aPattern
+ * @return true if the specified portion of the text matches the pattern
+ * @param String <code>text</code>, a String object that contains the substring to match
+ * @param int <code>start<code> marks the starting position (inclusive) of the substring
+ * @param int <code>end<code> marks the ending index (exclusive) of the substring
+ */
+ public boolean match(String text, int start, int end) {
+ if (null == text)
+ throw new IllegalArgumentException();
+
+ if (start > end)
+ return false;
+
+ if (fIgnoreWildCards)
+ return (end - start == fLength) && fPattern.regionMatches(fIgnoreCase, 0, text, start, fLength);
+ int segCount= fSegments.length;
+ if (segCount == 0 && (fHasLeadingStar || fHasTrailingStar)) // pattern contains only '*'(s)
+ return true;
+ if (start == end)
+ return fLength == 0;
+ if (fLength == 0)
+ return start == end;
+
+ int tlen= text.length();
+ if (start < 0)
+ start= 0;
+ if (end > tlen)
+ end= tlen;
+
+ int tCurPos= start;
+ int bound= end - fBound;
+ if ( bound < 0)
+ return false;
+ int i=0;
+ String current= fSegments[i];
+ int segLength= current.length();
+
+ /* process first segment */
+ if (!fHasLeadingStar){
+ if(!regExpRegionMatches(text, start, current, 0, segLength)) {
+ return false;
+ } else {
+ ++i;
+ tCurPos= tCurPos + segLength;
+ }
+ }
+
+ /* process middle segments */
+ while (i < segCount) {
+ current= fSegments[i];
+ int currentMatch;
+ int k= current.indexOf(fSingleWildCard);
+ if (k < 0) {
+ currentMatch= textPosIn(text, tCurPos, end, current);
+ if (currentMatch < 0)
+ return false;
+ } else {
+ currentMatch= regExpPosIn(text, tCurPos, end, current);
+ if (currentMatch < 0)
+ return false;
+ }
+ tCurPos= currentMatch + current.length();
+ i++;
+ }
+
+ /* process final segment */
+ if (!fHasTrailingStar && tCurPos != end) {
+ int clen= current.length();
+ return regExpRegionMatches(text, end - clen, current, 0, clen);
+ }
+ return i == segCount ;
+ }
+ /**
+ * This method parses the given pattern into segments seperated by wildcard '*' characters.
+ * Since wildcards are not being used in this case, the pattern consists of a single segment.
+ */
+ private void parseNoWildCards() {
+ fSegments= new String[1];
+ fSegments[0]= fPattern;
+ fBound= fLength;
+ }
+ /**
+ * Parses the given pattern into segments seperated by wildcard '*' characters.
+ * @param p, a String object that is a simple regular expression with ‘*’ and/or ‘?’
+ */
+ private void parseWildCards() {
+ if(fPattern.startsWith("*"))//$NON-NLS-1$
+ fHasLeadingStar= true;
+ if(fPattern.endsWith("*")) {//$NON-NLS-1$
+ /* make sure it's not an escaped wildcard */
+ if (fLength > 1 && fPattern.charAt(fLength - 2) != '\\') {
+ fHasTrailingStar= true;
+ }
+ }
+
+ Vector temp= new Vector();
+
+ int pos= 0;
+ StringBuffer buf= new StringBuffer();
+ while (pos < fLength) {
+ char c= fPattern.charAt(pos++);
+ switch (c) {
+ case '\\':
+ if (pos >= fLength) {
+ buf.append(c);
+ } else {
+ char next= fPattern.charAt(pos++);
+ /* if it's an escape sequence */
+ if (next == '*' || next == '?' || next == '\\') {
+ buf.append(next);
+ } else {
+ /* not an escape sequence, just insert literally */
+ buf.append(c);
+ buf.append(next);
+ }
+ }
+ break;
+ case '*':
+ if (buf.length() > 0) {
+ /* new segment */
+ temp.addElement(buf.toString());
+ fBound += buf.length();
+ buf.setLength(0);
+ }
+ break;
+ case '?':
+ /* append special character representing single match wildcard */
+ buf.append(fSingleWildCard);
+ break;
+ default:
+ buf.append(c);
+ }
+ }
+
+ /* add last buffer to segment list */
+ if (buf.length() > 0) {
+ temp.addElement(buf.toString());
+ fBound += buf.length();
+ }
+
+ fSegments= new String[temp.size()];
+ temp.copyInto(fSegments);
+ }
+ /**
+ * @param <code>text</code>, a string which contains no wildcard
+ * @param <code>start</code>, the starting index in the text for search, inclusive
+ * @param <code>end</code>, the stopping point of search, exclusive
+ * @return the starting index in the text of the pattern , or -1 if not found
+ */
+ protected int posIn(String text, int start, int end) {//no wild card in pattern
+ int max= end - fLength;
+
+ if (!fIgnoreCase) {
+ int i= text.indexOf(fPattern, start);
+ if (i == -1 || i > max)
+ return -1;
+ return i;
+ }
+
+ for (int i= start; i <= max; ++i) {
+ if (text.regionMatches(true, i, fPattern, 0, fLength))
+ return i;
+ }
+
+ return -1;
+ }
+ /**
+ * @param <code>text</code>, a simple regular expression that may only contain '?'(s)
+ * @param <code>start</code>, the starting index in the text for search, inclusive
+ * @param <code>end</code>, the stopping point of search, exclusive
+ * @param <code>p</code>, a simple regular expression that may contains '?'
+ * @param <code>caseIgnored</code>, wether the pattern is not casesensitive
+ * @return the starting index in the text of the pattern , or -1 if not found
+ */
+ protected int regExpPosIn(String text, int start, int end, String p) {
+ int plen= p.length();
+
+ int max= end - plen;
+ for (int i= start; i <= max; ++i) {
+ if (regExpRegionMatches(text, i, p, 0, plen))
+ return i;
+ }
+ return -1;
+ }
+ /**
+ *
+ * @return boolean
+ * @param <code>text</code>, a String to match
+ * @param <code>start</code>, int that indicates the starting index of match, inclusive
+ * @param <code>end</code> int that indicates the ending index of match, exclusive
+ * @param <code>p</code>, String, String, a simple regular expression that may contain '?'
+ * @param <code>ignoreCase</code>, boolean indicating wether code>p</code> is case sensitive
+ */
+ protected boolean regExpRegionMatches(String text, int tStart, String p, int pStart, int plen) {
+ while (plen-- > 0) {
+ char tchar= text.charAt(tStart++);
+ char pchar= p.charAt(pStart++);
+
+ /* process wild cards */
+ if (!fIgnoreWildCards) {
+ /* skip single wild cards */
+ if (pchar == fSingleWildCard) {
+ continue;
+ }
+ }
+ if (pchar == tchar)
+ continue;
+ if (fIgnoreCase) {
+ if (Character.toUpperCase(tchar) == Character.toUpperCase(pchar))
+ continue;
+ // comparing after converting to upper case doesn't handle all cases;
+ // also compare after converting to lower case
+ if (Character.toLowerCase(tchar) == Character.toLowerCase(pchar))
+ continue;
+ }
+ return false;
+ }
+ return true;
+ }
+ /**
+ * @param <code>text</code>, the string to match
+ * @param <code>start</code>, the starting index in the text for search, inclusive
+ * @param <code>end</code>, the stopping point of search, exclusive
+ * @param code>p</code>, a string that has no wildcard
+ * @param <code>ignoreCase</code>, boolean indicating wether code>p</code> is case sensitive
+ * @return the starting index in the text of the pattern , or -1 if not found
+ */
+ protected int textPosIn(String text, int start, int end, String p) {
+
+ int plen= p.length();
+ int max= end - plen;
+
+ if (!fIgnoreCase) {
+ int i= text.indexOf(p, start);
+ if (i == -1 || i > max)
+ return -1;
+ return i;
+ }
+
+ for (int i= start; i <= max; ++i) {
+ if (text.regionMatches(true, i, p, 0, plen))
+ return i;
+ }
+
+ return -1;
+ }
+}
\ No newline at end of file
--- /dev/null
+package net.sourceforge.phpdt.internal.ui.util;
+
+import java.util.Comparator;
+import org.eclipse.jface.util.Assert;
+
+/**
+ * Quick sort to sort key-value pairs. The keys and arrays are specified
+ * in separate arrays.
+ */
+public class TwoArrayQuickSorter {
+
+ private Comparator fComparator;
+
+ /**
+ * Default comparator.
+ */
+ public static final class StringComparator implements Comparator {
+ private boolean fIgnoreCase;
+
+ StringComparator(boolean ignoreCase) {
+ fIgnoreCase= ignoreCase;
+ }
+
+ public int compare(Object left, Object right) {
+ return fIgnoreCase
+ ? ((String) left).compareToIgnoreCase((String) right)
+ : ((String) left).compareTo((String) right);
+ }
+ }
+
+ /**
+ * Creates a sorter with default string comparator.
+ * The keys are assumed to be strings.
+ * @param ignoreCase specifies whether sorting is case sensitive or not.
+ */
+ public TwoArrayQuickSorter(boolean ignoreCase) {
+ fComparator= new StringComparator(ignoreCase);
+ }
+
+ /**
+ * Creates a sorter with a comparator.
+ * @param comparator the comparator to order the elements. The comparator must not be <code>null</code>.
+ */
+ public TwoArrayQuickSorter(Comparator comparator) {
+ fComparator= comparator;
+ }
+
+ /**
+ * Sorts keys and values in parallel.
+ * @param keys the keys to use for sorting.
+ * @param values the values associated with the keys.
+ */
+ public void sort(Object[] keys, Object[] values) {
+ if ((keys == null) || (values == null)) {
+ Assert.isTrue(false, "Either keys or values in null"); //$NON-NLS-1$
+ return;
+ }
+
+ if (keys.length <= 1)
+ return;
+
+ internalSort(keys, values, 0, keys.length - 1);
+ }
+
+ private void internalSort(Object[] keys, Object[] values, int left, int right) {
+ int original_left= left;
+ int original_right= right;
+
+ Object mid= keys[(left + right) / 2];
+ do {
+ while (fComparator.compare(keys[left], mid) < 0)
+ left++;
+
+ while (fComparator.compare(mid, keys[right]) < 0)
+ right--;
+
+ if (left <= right) {
+ swap(keys, left, right);
+ swap(values, left, right);
+ left++;
+ right--;
+ }
+ } while (left <= right);
+
+ if (original_left < right)
+ internalSort(keys , values, original_left, right);
+
+ if (left < original_right)
+ internalSort(keys, values, left, original_right);
+ }
+
+ /*
+ * Swaps x[a] with x[b].
+ */
+ private static final void swap(Object x[], int a, int b) {
+ Object t = x[a];
+ x[a] = x[b];
+ x[b] = t;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package net.sourceforge.phpdt.internal.ui.viewsupport;
+
+import java.util.ArrayList;
+
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTreeViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.ITreeViewerListener;
+import org.eclipse.jface.viewers.TreeExpansionEvent;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Item;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ * CheckboxTreeViewer with special behaviour of the checked / gray state on
+ * container (non-leaf) nodes:
+ * The grayed state is used to visualize the checked state of its children.
+ * Containers are checked and non-gary if all contained leafs are checked. The
+ * container is grayed if some but not all leafs are checked.
+ */
+public class ContainerCheckedTreeViewer extends CheckboxTreeViewer {
+
+ /**
+ * Constructor for ContainerCheckedTreeViewer.
+ * @see CheckboxTreeViewer#CheckboxTreeViewer(Composite)
+ */
+ public ContainerCheckedTreeViewer(Composite parent) {
+ super(parent);
+ initViewer();
+ }
+
+ /**
+ * Constructor for ContainerCheckedTreeViewer.
+ * @see CheckboxTreeViewer#CheckboxTreeViewer(Composite,int)
+ */
+ public ContainerCheckedTreeViewer(Composite parent, int style) {
+ super(parent, style);
+ initViewer();
+ }
+
+ /**
+ * Constructor for ContainerCheckedTreeViewer.
+ * @see CheckboxTreeViewer#CheckboxTreeViewer(Tree)
+ */
+ public ContainerCheckedTreeViewer(Tree tree) {
+ super(tree);
+ initViewer();
+ }
+
+ private void initViewer() {
+ setUseHashlookup(true);
+ addCheckStateListener(new ICheckStateListener() {
+ public void checkStateChanged(CheckStateChangedEvent event) {
+ doCheckStateChanged(event.getElement());
+ }
+ });
+ addTreeListener(new ITreeViewerListener() {
+ public void treeCollapsed(TreeExpansionEvent event) {}
+ public void treeExpanded(TreeExpansionEvent event) {
+ Widget item = findItem(event.getElement());
+ if (item instanceof TreeItem) {
+ initializeItem((TreeItem) item);
+ }
+ }
+ });
+ }
+
+ protected void doCheckStateChanged(Object element) {
+ Widget item = findItem(element);
+ if (item instanceof TreeItem) {
+ TreeItem treeItem = (TreeItem) item;
+ treeItem.setGrayed(false);
+ updateChildrenItems(treeItem);
+ updateParentItems(treeItem.getParentItem());
+ }
+ }
+
+ /**
+ * The item has expanded. Updates the checked state of its children.
+ */
+ private void initializeItem(TreeItem item) {
+ if (item.getChecked() && !item.getGrayed()) {
+ updateChildrenItems((TreeItem) item);
+ }
+ }
+
+ /**
+ * Updates the check state of all created children
+ */
+ private void updateChildrenItems(TreeItem parent) {
+ Item[] children = getChildren(parent);
+ boolean state = parent.getChecked();
+ for (int i = 0; i < children.length; i++) {
+ TreeItem curr = (TreeItem) children[i];
+ if (curr.getData() != null && ((curr.getChecked() != state) || curr.getGrayed())) {
+ curr.setChecked(state);
+ curr.setGrayed(false);
+ updateChildrenItems(curr);
+ }
+ }
+ }
+
+ /**
+ * Updates the check / gray state of all parent items
+ */
+ private void updateParentItems(TreeItem item) {
+ if (item != null) {
+ Item[] children = getChildren(item);
+ boolean containsChecked = false;
+ boolean containsUnchecked = false;
+ for (int i = 0; i < children.length; i++) {
+ TreeItem curr = (TreeItem) children[i];
+ containsChecked |= curr.getChecked();
+ containsUnchecked |= (!curr.getChecked() || curr.getGrayed());
+ }
+ item.setChecked(containsChecked);
+ item.setGrayed(containsChecked && containsUnchecked);
+ updateParentItems(item.getParentItem());
+ }
+ }
+
+ public boolean setChecked(Object element, boolean state) {
+ if (super.setChecked(element, state)) {
+ doCheckStateChanged(element);
+ return true;
+ }
+ return false;
+ }
+
+ public void setCheckedElements(Object[] elements) {
+ super.setCheckedElements(elements);
+ for (int i = 0; i < elements.length; i++) {
+ doCheckStateChanged(elements[i]);
+ }
+ }
+
+ protected void setExpanded(Item item, boolean expand) {
+ super.setExpanded(item, expand);
+ if (expand && item instanceof TreeItem) {
+ initializeItem((TreeItem) item);
+ }
+ }
+
+ public Object[] getCheckedElements() {
+ Object[] checked = super.getCheckedElements();
+ // add all items that are children of a checked node but not created yet
+ ArrayList result = new ArrayList();
+ for (int i = 0; i < checked.length; i++) {
+ Object curr = checked[i];
+ result.add(curr);
+ Widget item = findItem(curr);
+ if (item != null) {
+ Item[] children = getChildren(item);
+ // check if contains the dummy node
+ if (children.length == 1 && children[0].getData() == null) {
+ // not yet created
+ collectChildren(curr, result);
+ }
+ }
+ }
+ return result.toArray();
+ }
+
+ private void collectChildren(Object element, ArrayList result) {
+ Object[] filteredChildren = getFilteredChildren(element);
+ for (int i = 0; i < filteredChildren.length; i++) {
+ Object curr = filteredChildren[i];
+ result.add(curr);
+ collectChildren(curr, result);
+ }
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui.viewsupport;
+
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+import net.sourceforge.phpdt.internal.ui.util.SWTUtil;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.util.Assert;
+
+/**
+ * A registry that maps <code>ImageDescriptors</code> to <code>Image</code>.
+ */
+public class ImageDescriptorRegistry {
+
+ private HashMap fRegistry= new HashMap(10);
+ private Display fDisplay;
+
+ /**
+ * Creates a new image descriptor registry for the current or default display,
+ * respectively.
+ */
+ public ImageDescriptorRegistry() {
+ this(SWTUtil.getStandardDisplay());
+ }
+
+ /**
+ * Creates a new image descriptor registry for the given display. All images
+ * managed by this registry will be disposed when the display gets disposed.
+ *
+ * @param diaplay the display the images managed by this registry are allocated for
+ */
+ public ImageDescriptorRegistry(Display display) {
+ fDisplay= display;
+ Assert.isNotNull(fDisplay);
+ hookDisplay();
+ }
+
+ /**
+ * Returns the image assiciated with the given image descriptor.
+ *
+ * @param descriptor the image descriptor for which the registry manages an image
+ * @return the image associated with the image descriptor or <code>null</code>
+ * if the image descriptor can't create the requested image.
+ */
+ public Image get(ImageDescriptor descriptor) {
+ if (descriptor == null)
+ descriptor= ImageDescriptor.getMissingImageDescriptor();
+
+ Image result= (Image)fRegistry.get(descriptor);
+ if (result != null)
+ return result;
+
+ Assert.isTrue(fDisplay == SWTUtil.getStandardDisplay(), "Allocating image for wrong display."); //$NON-NLS-1$
+ result= descriptor.createImage();
+ if (result != null)
+ fRegistry.put(descriptor, result);
+ return result;
+ }
+
+ /**
+ * Disposes all images managed by this registry.
+ */
+ public void dispose() {
+ for (Iterator iter= fRegistry.values().iterator(); iter.hasNext(); ) {
+ Image image= (Image)iter.next();
+ image.dispose();
+ }
+ fRegistry.clear();
+ }
+
+ private void hookDisplay() {
+ fDisplay.disposeExec(new Runnable() {
+ public void run() {
+ dispose();
+ }
+ });
+ }
+}
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<templates>
+<template name="class" description="class template with constructor" context="php" enabled="true">class ${class_name} {
+ function ${class_name}() {
+ ${cursor}
+ }
+}</template>
+<template name="class" description="class with attribute" context="php" enabled="true">class ${class_name} {
+ var $$${attribute};
+ function ${class_name}() {
+ ${cursor}
+ }
+
+ function set_${attribute}( $$${attr} ) {
+ $$this->${attribute} = $$${attr};
+ }
+
+ function get_${attribute}() {
+ return $$this->${attribute};
+ }
+}</template>
+<template name="for" description="iterate over array" context="php" enabled="true">for ($$${index} = 0; $$${index} < sizeof($$${array}); $$${index}++) {
+ ${cursor}
+}</template>
+<template name="for" description="iterate over array w/ temporary variable" context="php" enabled="true">for ($$${index} = 0; $$${index} < sizeof($$${array}); $$${index}++) {
+ $$${array_element} = $$${array}[$$${index}];
+ ${cursor}
+}</template>
+<template name="function" description="function template" context="php" enabled="true">function ${function_name} () {
+ ${cursor}
+}</template>
+<template name="function" description="function template with return" context="php" enabled="true">function ${function_name} () {
+ return (${cursor});
+}</template>
+<template name="while" description="while iteration" context="php" enabled="true">while (${condition}) {
+ ${cursor}
+}</template>
+<template name="switch" description="switch case statement" context="php" enabled="true">switch (${key}) {
+ case ${value}:
+ ${cursor}
+ break;
+
+ default:
+ break;
+}</template><template name="if" description="if statement" context="php" enabled="true">if (${condition}) {
+ ${cursor}
+}</template><template name="ifelse" description="if else statement" context="php" enabled="true">if (${condition}) {
+ ${cursor}
+} else {
+
+}</template><template name="elseif" description="else if block" context="php" enabled="true">elseif (${condition}) {
+ ${cursor}
+}</template><template name="else" description="else block" context="php" enabled="true">else {
+ ${cursor}
+}</template>
+<template name="filecomment" description="file comment used by the class and interface wizards" context="php" enabled="true">/**
+ * Created on ${date} by ${user}
+ *
+ */</template><template name="functioncomment" description="function comment" context="php" enabled="true">/**
+ * @author ${user}
+ *
+ */</template>
+ <template name="echo" description="echo a string" context="php" enabled="true">echo "${string}";
+ ${cursor}</template>
+ </templates>
\ No newline at end of file