| @@ -0,0 +1,249 @@ | ||
| /******************************************************************************* | ||
| * Copyright (c) 2000, 2011 IBM Corporation and others. | ||
| * All rights reserved. This program and the accompanying materials | ||
| * are made available under the terms of the Eclipse Public License v1.0 | ||
| * which accompanies this distribution, and is available at | ||
| * http://www.eclipse.org/legal/epl-v10.html | ||
| * | ||
| * Contributors: | ||
| * IBM Corporation - initial API and implementation | ||
| *******************************************************************************/ | ||
| package com.aptana.editor.php.internal.ui.wizard; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| import org.eclipse.core.runtime.Assert; | ||
| import org.eclipse.jface.viewers.ColumnLayoutData; | ||
| import org.eclipse.jface.viewers.ColumnPixelData; | ||
| import org.eclipse.jface.viewers.ColumnWeightData; | ||
| import org.eclipse.swt.SWT; | ||
| import org.eclipse.swt.events.ControlAdapter; | ||
| import org.eclipse.swt.events.ControlEvent; | ||
| import org.eclipse.swt.graphics.Point; | ||
| import org.eclipse.swt.graphics.Rectangle; | ||
| import org.eclipse.swt.widgets.Composite; | ||
| import org.eclipse.swt.widgets.Table; | ||
| import org.eclipse.swt.widgets.TableColumn; | ||
|
|
||
| /** | ||
| * A special composite to layout columns inside a table. The composite is needed since we have to layout the columns | ||
| * "before" the actual table gets layouted. Hence we can't use a normal layout manager. | ||
| * <p> | ||
| * </p> | ||
| */ | ||
| public class TableLayoutComposite extends Composite | ||
| { | ||
|
|
||
| /** | ||
| * The number of extra pixels taken as horizontal trim by the table column. To ensure there are N pixels available | ||
| * for the content of the column, assign N+COLUMN_TRIM for the column width. | ||
| * <p> | ||
| * XXX: Should either switch to use {@link org.eclipse.jface.layout.TableColumnLayout} or get API from JFace or SWT, | ||
| * see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=218483 | ||
| * </p> | ||
| * | ||
| * @since 3.1 | ||
| */ | ||
| private static int COLUMN_TRIM; | ||
| static | ||
| { | ||
| String platform = SWT.getPlatform(); | ||
| if ("win32".equals(platform)) //$NON-NLS-1$ | ||
| { | ||
| COLUMN_TRIM = 4; | ||
| } | ||
| else if ("carbon".equals(platform)) //$NON-NLS-1$ | ||
| { | ||
| COLUMN_TRIM = 24; | ||
| } | ||
| else | ||
| { | ||
| COLUMN_TRIM = 3; | ||
| } | ||
|
|
||
| } | ||
|
|
||
| private List<ColumnLayoutData> columns = new ArrayList<ColumnLayoutData>(); | ||
|
|
||
| /** | ||
| * Creates a new <code>TableLayoutComposite</code>. | ||
| * | ||
| * @param parent | ||
| * the parent composite | ||
| * @param style | ||
| * the SWT style | ||
| */ | ||
| public TableLayoutComposite(Composite parent, int style) | ||
| { | ||
| super(parent, style); | ||
| addControlListener(new ControlAdapter() | ||
| { | ||
| public void controlResized(ControlEvent e) | ||
| { | ||
| Rectangle area = getClientArea(); | ||
| Table table = (Table) getChildren()[0]; | ||
| Point preferredSize = computeTableSize(table); | ||
| int width = area.width - 2 * table.getBorderWidth(); | ||
| if (preferredSize.y > area.height) | ||
| { | ||
| // Subtract the scrollbar width from the total column width | ||
| // if a vertical scrollbar will be required | ||
| Point vBarSize = table.getVerticalBar().getSize(); | ||
| width -= vBarSize.x; | ||
| } | ||
| layoutTable(table, width, area, table.getSize().x < area.width); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| /** | ||
| * Adds a new column of data to this table layout. | ||
| * | ||
| * @param data | ||
| * the column layout data | ||
| */ | ||
| public void addColumnData(ColumnLayoutData data) | ||
| { | ||
| columns.add(data); | ||
| } | ||
|
|
||
| // ---- Helpers ------------------------------------------------------------------------------------- | ||
|
|
||
| private Point computeTableSize(Table table) | ||
| { | ||
| Point result = table.computeSize(SWT.DEFAULT, SWT.DEFAULT); | ||
|
|
||
| int width = 0; | ||
| for (ColumnLayoutData layoutData : columns) | ||
| { | ||
| if (layoutData instanceof ColumnPixelData) | ||
| { | ||
| ColumnPixelData col = (ColumnPixelData) layoutData; | ||
| width += col.width; | ||
| if (col.addTrim) | ||
| { | ||
| width += COLUMN_TRIM; | ||
| } | ||
| } | ||
| else if (layoutData instanceof ColumnWeightData) | ||
| { | ||
| ColumnWeightData col = (ColumnWeightData) layoutData; | ||
| width += col.minimumWidth; | ||
| } | ||
| else | ||
| { | ||
| Assert.isTrue(false, "Unknown column layout data"); //$NON-NLS-1$ | ||
| } | ||
| } | ||
| if (width > result.x) | ||
| { | ||
| result.x = width; | ||
| } | ||
| return result; | ||
| } | ||
|
|
||
| private void layoutTable(Table table, int width, Rectangle area, boolean increase) | ||
| { | ||
| // XXX: Layout is being called with an invalid value the first time | ||
| // it is being called on Linux. This method resets the | ||
| // Layout to null so we make sure we run it only when | ||
| // the value is OK. | ||
| if (width <= 1) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| TableColumn[] tableColumns = table.getColumns(); | ||
| int size = Math.min(columns.size(), tableColumns.length); | ||
| int[] widths = new int[size]; | ||
| int fixedWidth = 0; | ||
| int numberOfWeightColumns = 0; | ||
| int totalWeight = 0; | ||
|
|
||
| // First calc space occupied by fixed columns | ||
| for (int i = 0; i < size; i++) | ||
| { | ||
| ColumnLayoutData col = (ColumnLayoutData) columns.get(i); | ||
| if (col instanceof ColumnPixelData) | ||
| { | ||
| ColumnPixelData cpd = (ColumnPixelData) col; | ||
| int pixels = cpd.width; | ||
| if (cpd.addTrim) | ||
| { | ||
| pixels += COLUMN_TRIM; | ||
| } | ||
| widths[i] = pixels; | ||
| fixedWidth += pixels; | ||
| } | ||
| else if (col instanceof ColumnWeightData) | ||
| { | ||
| ColumnWeightData cw = (ColumnWeightData) col; | ||
| numberOfWeightColumns++; | ||
| // first time, use the weight specified by the column data, otherwise use the actual width as the weight | ||
| // int weight = firstTime ? cw.weight : tableColumns[i].getWidth(); | ||
| int weight = cw.weight; | ||
| totalWeight += weight; | ||
| } | ||
| else | ||
| { | ||
| Assert.isTrue(false, "Unknown column layout data"); //$NON-NLS-1$ | ||
| } | ||
| } | ||
|
|
||
| // Do we have columns that have a weight | ||
| if (numberOfWeightColumns > 0) | ||
| { | ||
| // Now distribute the rest to the columns with weight. | ||
| int rest = width - fixedWidth; | ||
| int totalDistributed = 0; | ||
| for (int i = 0; i < size; ++i) | ||
| { | ||
| ColumnLayoutData col = (ColumnLayoutData) columns.get(i); | ||
| if (col instanceof ColumnWeightData) | ||
| { | ||
| ColumnWeightData cw = (ColumnWeightData) col; | ||
| // calculate weight as above | ||
| // int weight = firstTime ? cw.weight : tableColumns[i].getWidth(); | ||
| int weight = cw.weight; | ||
| int pixels = totalWeight == 0 ? 0 : weight * rest / totalWeight; | ||
| if (pixels < cw.minimumWidth) | ||
| { | ||
| pixels = cw.minimumWidth; | ||
| } | ||
| totalDistributed += pixels; | ||
| widths[i] = pixels; | ||
| } | ||
| } | ||
|
|
||
| // Distribute any remaining pixels to columns with weight. | ||
| int diff = rest - totalDistributed; | ||
| for (int i = 0; diff > 0; ++i) | ||
| { | ||
| if (i == size) | ||
| { | ||
| i = 0; | ||
| } | ||
| ColumnLayoutData col = (ColumnLayoutData) columns.get(i); | ||
| if (col instanceof ColumnWeightData) | ||
| { | ||
| ++widths[i]; | ||
| --diff; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (increase) | ||
| { | ||
| table.setSize(area.width, area.height); | ||
| } | ||
| for (int i = 0; i < size; i++) | ||
| { | ||
| tableColumns[i].setWidth(widths[i]); | ||
| } | ||
| if (!increase) | ||
| { | ||
| table.setSize(area.width, area.height); | ||
| } | ||
| } | ||
| } |
| @@ -0,0 +1,50 @@ | ||
| /******************************************************************************* | ||
| * Copyright (c) 2000, 2011 IBM Corporation and others. | ||
| * All rights reserved. This program and the accompanying materials | ||
| * are made available under the terms of the Eclipse Public License v1.0 | ||
| * which accompanies this distribution, and is available at | ||
| * http://www.eclipse.org/legal/epl-v10.html | ||
| * | ||
| * Contributors: | ||
| * IBM Corporation - initial API and implementation | ||
| *******************************************************************************/ | ||
| package com.aptana.editor.php.internal.ui.wizard.field; | ||
|
|
||
| import org.eclipse.php.internal.ui.wizard.field.ListDialogField; | ||
|
|
||
| /** | ||
| * Change listener used by <code>ListDialogField</code> and <code>CheckedListDialogField</code> | ||
| * | ||
| * @param <E> | ||
| * the type of the list elements | ||
| */ | ||
| public interface IListAdapter<E> | ||
| { | ||
|
|
||
| /** | ||
| * A button from the button bar has been pressed. | ||
| * | ||
| * @param field | ||
| * the dialog field | ||
| * @param index | ||
| * the button index | ||
| */ | ||
| void customButtonPressed(ListDialogField<E> field, int index); | ||
|
|
||
| /** | ||
| * The selection of the list has changed. | ||
| * | ||
| * @param field | ||
| * the dialog field | ||
| */ | ||
| void selectionChanged(ListDialogField<E> field); | ||
|
|
||
| /** | ||
| * An entry in the list has been double clicked | ||
| * | ||
| * @param field | ||
| * the dialog field | ||
| */ | ||
| void doubleClicked(ListDialogField<E> field); | ||
|
|
||
| } |
| @@ -0,0 +1,85 @@ | ||
| /******************************************************************************* | ||
| * Copyright (c) 2006 Zend Corporation and IBM Corporation. | ||
| * All rights reserved. This program and the accompanying materials | ||
| * are made available under the terms of the Eclipse Public License v1.0 | ||
| * which accompanies this distribution, and is available at | ||
| * http://www.eclipse.org/legal/epl-v10.html | ||
| * | ||
| * Contributors: | ||
| * Zend and IBM - Initial implementation | ||
| *******************************************************************************/ | ||
| package org.eclipse.php.internal.core.project; | ||
|
|
||
| import org.eclipse.core.runtime.IPath; | ||
|
|
||
| /** | ||
| * Interface of a include path container. A include path container provides a way to indirectly reference a set of | ||
| * include path entries through a include path entry of kind <code>CPE_CONTAINER</code>. Typically, a include path | ||
| * container can be used to describe a complex library composed of multiple JARs or projects, considering also that | ||
| * containers can map to different set of entries on each project, in other words, several projects can reference the | ||
| * same generic container path, but have each of them actually bound to a different container object. | ||
| * <p> | ||
| * The set of entries associated with a include path container may contain any of the following: | ||
| * <ul> | ||
| * <li>library entries (<code>CPE_LIBRARY</code>)</li> | ||
| * <li>project entries (<code>CPE_PROJECT</code>)</li> | ||
| * </ul> | ||
| * In particular, a include path container can neither reference further include path containers or include path | ||
| * variables. | ||
| * <p> | ||
| * IncludePath container values are persisted locally to the workspace, but are not preserved from a session to another. | ||
| * It is thus highly recommended to register a <code>IncludePathContainerInitializer</code> for each referenced | ||
| * container (through the extension point "org.eclipse.jdt.core.IncludePathContainerInitializer"). | ||
| * <p> | ||
| * | ||
| * @see IIncludePathEntry | ||
| * @since 2.0 | ||
| */ | ||
|
|
||
| public interface IIncludePathContainer | ||
| { | ||
| /** | ||
| * Kind for a container mapping (application library, system library or default system library, implicitly | ||
| * contributed by the runtime) | ||
| */ | ||
| public static enum KIND | ||
| { | ||
| K_APPLICATION, K_SYSTEM, K_DEFAULT_SYSTEM | ||
| }; | ||
|
|
||
| IIncludePathEntry[] getIncludePathEntries(); | ||
|
|
||
| /** | ||
| * Answers a readable description of this container | ||
| * | ||
| * @return String - a string description of the container | ||
| */ | ||
| String getDescription(); | ||
|
|
||
| /** | ||
| * Answers the kind of this container. Can be either: | ||
| * <ul> | ||
| * <li><code>K_APPLICATION</code> if this container maps to an application library</li> | ||
| * <li><code>K_SYSTEM</code> if this container maps to a system library</li> | ||
| * <li><code>K_DEFAULT_SYSTEM</code> if this container maps to a default system library (library implicitly | ||
| * contributed by the runtime).</li> | ||
| * </ul> | ||
| * Typically, system containers should be placed first on a build path. | ||
| * | ||
| * @return the kind of this container | ||
| */ | ||
| int getKind(); | ||
|
|
||
| /** | ||
| * Answers the container path identifying this container. A container path is formed by a first ID segment followed | ||
| * with extra segments, which can be used as additional hints for resolving to this container. | ||
| * <p> | ||
| * The container ID is also used to identify a<code>IncludePathContainerInitializer</code> registered on the | ||
| * extension point "org.eclipse.jdt.core.include pathContainerInitializer", which can be invoked if needing to | ||
| * resolve the container before it is explicitly set. | ||
| * <p> | ||
| * | ||
| * @return IPath - the container path that is associated with this container | ||
| */ | ||
| IPath getPath(); | ||
| } |
| @@ -0,0 +1,69 @@ | ||
| /******************************************************************************* | ||
| * Copyright (c) 2006 Zend Corporation and IBM Corporation. | ||
| * All rights reserved. This program and the accompanying materials | ||
| * are made available under the terms of the Eclipse Public License v1.0 | ||
| * which accompanies this distribution, and is available at | ||
| * http://www.eclipse.org/legal/epl-v10.html | ||
| * | ||
| * Contributors: | ||
| * Zend and IBM - Initial implementation | ||
| *******************************************************************************/ | ||
| package org.eclipse.php.internal.core.project; | ||
|
|
||
| import org.eclipse.core.resources.IResource; | ||
| import org.eclipse.core.runtime.IPath; | ||
|
|
||
| public interface IIncludePathEntry | ||
| { | ||
|
|
||
| int K_SOURCE = 1; | ||
| /** | ||
| * Kind constant for a binary path root. Indicates this root only contains binary files. | ||
| */ | ||
| int K_BINARY = 2; | ||
|
|
||
| int IPE_LIBRARY = 1; | ||
|
|
||
| /** | ||
| * Entry kind constant describing a includepath entry identifying a required project. | ||
| */ | ||
| int IPE_PROJECT = 2; | ||
|
|
||
| /** | ||
| * Entry kind constant describing a includepath entry identifying a folder containing package fragments with source | ||
| * code to be compiled. | ||
| */ | ||
| int IPE_SOURCE = 3; | ||
|
|
||
| /** | ||
| * Entry kind constant describing a includepath entry defined using a path that begins with a includepath variable | ||
| * reference. | ||
| */ | ||
| int IPE_VARIABLE = 4; | ||
|
|
||
| /** | ||
| * Entry kind constant describing a includepath entry representing a name includepath container. | ||
| * | ||
| * @since 2.0 | ||
| */ | ||
| int IPE_CONTAINER = 5; | ||
|
|
||
| /** | ||
| * Entry kind constant describing a includepath entry identifying a JRE. | ||
| */ | ||
| int IPE_JRE = 6; | ||
|
|
||
| int getContentKind(); | ||
|
|
||
| int getEntryKind(); | ||
|
|
||
| IPath getPath(); | ||
|
|
||
| IResource getResource(); | ||
|
|
||
| boolean isExported(); | ||
|
|
||
| String validate(); | ||
|
|
||
| void setResource(IResource resource); | ||
| } |
| @@ -0,0 +1,21 @@ | ||
| /******************************************************************************* | ||
| * Copyright (c) 2006 Zend Corporation and IBM Corporation. | ||
| * All rights reserved. This program and the accompanying materials | ||
| * are made available under the terms of the Eclipse Public License v1.0 | ||
| * which accompanies this distribution, and is available at | ||
| * http://www.eclipse.org/legal/epl-v10.html | ||
| * | ||
| * Contributors: | ||
| * Zend and IBM - Initial implementation | ||
| *******************************************************************************/ | ||
| package org.eclipse.php.internal.core.project.options; | ||
|
|
||
| /** | ||
| * This listener listens to changes for a specific option in a set project It is invoked when the option is changed and | ||
| * it gets the old and new options - they can be object, but most likely strings. | ||
| */ | ||
| public interface IPhpProjectOptionChangeListener | ||
| { | ||
|
|
||
| public void notifyOptionChanged(Object oldOption, Object newOption); | ||
| } |
| @@ -0,0 +1,160 @@ | ||
| /******************************************************************************* | ||
| * Copyright (c) 2006 Zend Corporation and IBM Corporation. | ||
| * All rights reserved. This program and the accompanying materials | ||
| * are made available under the terms of the Eclipse Public License v1.0 | ||
| * which accompanies this distribution, and is available at | ||
| * http://www.eclipse.org/legal/epl-v10.html | ||
| * | ||
| * Contributors: | ||
| * Zend and IBM - Initial implementation | ||
| *******************************************************************************/ | ||
| package org.eclipse.php.internal.core.project.options.includepath; | ||
|
|
||
| import java.util.HashMap; | ||
| import java.util.Map; | ||
|
|
||
| import org.eclipse.core.runtime.IPath; | ||
| import org.eclipse.php.internal.core.project.IIncludePathEntry; | ||
| import org.eclipse.php.internal.core.util.preferences.IXMLPreferencesStorable; | ||
|
|
||
| import com.aptana.core.util.StringUtil; | ||
|
|
||
| public class IncludePathEntryDescriptor implements IXMLPreferencesStorable | ||
| { | ||
|
|
||
| private String entryKind = StringUtil.EMPTY; | ||
| private String contentKind = StringUtil.EMPTY; | ||
| private String path = StringUtil.EMPTY; | ||
| private String resourceName = StringUtil.EMPTY; | ||
| private boolean isExported = false; | ||
| private boolean createdReference = false; | ||
|
|
||
| public IncludePathEntryDescriptor() | ||
| { | ||
| } | ||
|
|
||
| public String getContentKind() | ||
| { | ||
| return contentKind; | ||
| } | ||
|
|
||
| public void setContentKind(String contentKind) | ||
| { | ||
| this.contentKind = contentKind; | ||
| } | ||
|
|
||
| public boolean isCreatedReference() | ||
| { | ||
| return createdReference; | ||
| } | ||
|
|
||
| public void setCreatedReference(boolean createdReference) | ||
| { | ||
| this.createdReference = createdReference; | ||
| } | ||
|
|
||
| public String getEntryKind() | ||
| { | ||
| return entryKind; | ||
| } | ||
|
|
||
| public void setEntryKind(String entryKind) | ||
| { | ||
| this.entryKind = entryKind; | ||
| } | ||
|
|
||
| public boolean isExported() | ||
| { | ||
| return isExported; | ||
| } | ||
|
|
||
| public void setExported(boolean isExported) | ||
| { | ||
| this.isExported = isExported; | ||
| } | ||
|
|
||
| public String getPath() | ||
| { | ||
| return path; | ||
| } | ||
|
|
||
| public void setPath(String path) | ||
| { | ||
| this.path = path; | ||
| } | ||
|
|
||
| public String getResourceName() | ||
| { | ||
| return resourceName; | ||
| } | ||
|
|
||
| public void setResourceName(String resourceName) | ||
| { | ||
| this.resourceName = resourceName; | ||
| } | ||
|
|
||
| public IncludePathEntryDescriptor(IncludePathEntry entry, IPath projectPath) | ||
| { | ||
| this.entryKind = IncludePathEntry.entryKindToString(entry.entryKind); | ||
| this.contentKind = IncludePathEntry.contentKindToString(entry.contentKind); | ||
| // path = entry.path.toOSString(); | ||
| if (entry.resource != null) | ||
| { | ||
| this.resourceName = entry.resource.getName(); | ||
| } | ||
| this.isExported = entry.isExported; | ||
| this.createdReference = false; | ||
|
|
||
| IPath entryPath = entry.path; | ||
| if (entry.entryKind != IIncludePathEntry.IPE_VARIABLE && entry.entryKind != IIncludePathEntry.IPE_CONTAINER) | ||
| { | ||
| // translate to project relative from absolute (unless a device path) | ||
| if (projectPath != null && projectPath.isPrefixOf(entryPath)) | ||
| { | ||
| if (entryPath.segment(0).equals(projectPath.segment(0))) | ||
| { | ||
| entryPath = entryPath.removeFirstSegments(1); | ||
| entryPath = entryPath.makeRelative(); | ||
| } | ||
| else | ||
| { | ||
| entryPath = entryPath.makeAbsolute(); | ||
| } | ||
| } | ||
| } | ||
| this.path = String.valueOf(entryPath); | ||
| } | ||
|
|
||
| @SuppressWarnings("rawtypes") | ||
| public void restoreFromMap(Map map) | ||
| { | ||
| Map entry = (Map) map.get("javabridge_entry"); //$NON-NLS-1$ | ||
| if (entry != null) | ||
| { | ||
| entryKind = (String) entry.get("entryKind"); //$NON-NLS-1$ | ||
| contentKind = (String) entry.get("contentKind"); //$NON-NLS-1$ | ||
| path = (String) entry.get("path"); //$NON-NLS-1$ | ||
| resourceName = (String) entry.get("resourceName"); //$NON-NLS-1$ | ||
| isExported = (Boolean.valueOf((String) entry.get("isExported"))).booleanValue(); //$NON-NLS-1$ | ||
| createdReference = (Boolean.valueOf((String) entry.get("referenceWasCreated"))).booleanValue(); //$NON-NLS-1$ | ||
| } | ||
| } | ||
|
|
||
| @SuppressWarnings("rawtypes") | ||
| public Map storeToMap() | ||
| { | ||
| Map<String, Comparable> map = new HashMap<String, Comparable>(6); | ||
| map.put("entryKind", entryKind); //$NON-NLS-1$ | ||
| map.put("contentKind", contentKind); //$NON-NLS-1$ | ||
| map.put("path", path); //$NON-NLS-1$ | ||
| map.put("resourceName", resourceName); //$NON-NLS-1$ | ||
| map.put("isExported", new Boolean(isExported)); //$NON-NLS-1$ | ||
| map.put("referenceWasCreated", new Boolean(createdReference)); //$NON-NLS-1$ | ||
|
|
||
| Map<String, Map> entry = new HashMap<String, Map>(1); | ||
| entry.put("javabridge_entry", map); //$NON-NLS-1$ | ||
|
|
||
| return entry; | ||
| } | ||
|
|
||
| } |
| @@ -0,0 +1,252 @@ | ||
| /******************************************************************************* | ||
| * Copyright (c) 2006 Zend Corporation and IBM Corporation. | ||
| * All rights reserved. This program and the accompanying materials | ||
| * are made available under the terms of the Eclipse Public License v1.0 | ||
| * which accompanies this distribution, and is available at | ||
| * http://www.eclipse.org/legal/epl-v10.html | ||
| * | ||
| * Contributors: | ||
| * Zend and IBM - Initial implementation | ||
| *******************************************************************************/ | ||
| package org.eclipse.php.internal.core.project.options.includepath; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.HashMap; | ||
| import java.util.HashSet; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.Set; | ||
|
|
||
| import org.eclipse.core.runtime.IConfigurationElement; | ||
| import org.eclipse.core.runtime.IPath; | ||
| import org.eclipse.core.runtime.Path; | ||
| import org.eclipse.core.runtime.Platform; | ||
| import org.eclipse.core.runtime.Plugin; | ||
| import org.eclipse.core.runtime.SubProgressMonitor; | ||
| import org.eclipse.jface.preference.IPreferenceStore; | ||
|
|
||
| import com.aptana.core.util.CollectionsUtil; | ||
| import com.aptana.core.util.StringUtil; | ||
| import com.aptana.editor.php.core.IPHPCoreEPLConstants; | ||
| import com.aptana.editor.php.epl.PHPEplPlugin; | ||
|
|
||
| public class IncludePathVariableManager | ||
| { | ||
|
|
||
| private static final String COMMA = ","; //$NON-NLS-1$ | ||
| private static IncludePathVariableManager instance; | ||
|
|
||
| public static IncludePathVariableManager instance() | ||
| { | ||
| if (instance == null) | ||
| { | ||
| instance = new IncludePathVariableManager(); | ||
| } | ||
| return instance; | ||
| } | ||
|
|
||
| IPreferenceStore preferenceStore = PHPEplPlugin.getDefault().getPreferenceStore(); | ||
|
|
||
| private Map<String, IPath> variables; | ||
| private Set<String> reservedVariables; | ||
| private List<IncludePathVariablesListener> listeners; | ||
|
|
||
| private IncludePathVariableManager() | ||
| { | ||
| variables = new HashMap<String, IPath>(); | ||
| reservedVariables = new HashSet<String>(); | ||
| } | ||
|
|
||
| public IPath getIncludePathVariable(String variableName) | ||
| { | ||
| IPath varPath = null; | ||
| IPath path = new Path(variableName); | ||
| if (path.segmentCount() == 1) | ||
| { | ||
| varPath = (IPath) variables.get(variableName); | ||
| } | ||
| else | ||
| { | ||
| varPath = (IPath) variables.get(path.segment(0)); | ||
| if (varPath != null) | ||
| { | ||
| varPath = varPath.append(path.removeFirstSegments(1)); | ||
| } | ||
| } | ||
| return varPath; | ||
| } | ||
|
|
||
| public void setIncludePathVariables(String[] names, IPath[] paths, SubProgressMonitor monitor) | ||
| { | ||
| variables.clear(); | ||
| StringBuffer namesString = new StringBuffer(); | ||
| StringBuffer pathsString = new StringBuffer(); | ||
| for (int i = 0; i < names.length; i++) | ||
| { | ||
| if (paths[i] != null) | ||
| { | ||
| variables.put(names[i], paths[i]); | ||
| if (i > 0) | ||
| { | ||
| namesString.append(COMMA); | ||
| pathsString.append(COMMA); | ||
| } | ||
| namesString.append(names[i]); | ||
| pathsString.append(paths[i].toOSString()); | ||
| } | ||
| } | ||
| preferenceStore.setValue(IPHPCoreEPLConstants.INCLUDE_PATH_VARIABLE_NAMES, namesString.toString()); | ||
| preferenceStore.setValue(IPHPCoreEPLConstants.INCLUDE_PATH_VARIABLE_PATHS, pathsString.toString()); | ||
| fireIncludePathVariablesChanged(names, paths); | ||
| } | ||
|
|
||
| private void fireIncludePathVariablesChanged(String[] names, IPath[] paths) | ||
| { | ||
| if (CollectionsUtil.isEmpty(listeners)) | ||
| { | ||
| return; | ||
| } | ||
| for (IncludePathVariablesListener listener : listeners) | ||
| { | ||
| listener.includePathVariablesChanged(names, paths); | ||
| } | ||
|
|
||
| } | ||
|
|
||
| public void addListener(IncludePathVariablesListener listener) | ||
| { | ||
| if (listeners == null) | ||
| { | ||
| listeners = new ArrayList<IncludePathVariablesListener>(1); | ||
| } | ||
| if (!listeners.contains(listener)) | ||
| { | ||
| listeners.add(listener); | ||
| } | ||
| } | ||
|
|
||
| public void removeListener(IncludePathVariablesListener listener) | ||
| { | ||
| if (CollectionsUtil.isEmpty(listeners)) | ||
| { | ||
| return; | ||
| } | ||
| listeners.remove(listener); | ||
| } | ||
|
|
||
| public String[] getIncludePathVariableNames() | ||
| { | ||
| return (String[]) variables.keySet().toArray(new String[variables.size()]); | ||
|
|
||
| } | ||
|
|
||
| public void startUp() | ||
| { | ||
| String namesString = preferenceStore.getString(IPHPCoreEPLConstants.INCLUDE_PATH_VARIABLE_NAMES); | ||
| String pathsString = preferenceStore.getString(IPHPCoreEPLConstants.INCLUDE_PATH_VARIABLE_PATHS); | ||
| String[] names = {}; | ||
| if (namesString.length() > 0) | ||
| { | ||
| names = namesString.split(COMMA); | ||
| } | ||
| String[] paths = {}; | ||
| if (pathsString.length() > 0) | ||
| { | ||
| paths = pathsString.split(COMMA); | ||
| } | ||
| // Not good since empty paths are allowed!!! | ||
| // assert (names.length == paths.length); | ||
| for (int i = 0; i < names.length; i++) | ||
| { | ||
| String path; | ||
| if (i < paths.length) | ||
| { | ||
| path = paths[i]; | ||
| } | ||
| else | ||
| { | ||
| path = StringUtil.EMPTY; | ||
| } | ||
| variables.put(names[i], new Path(path)); | ||
| } | ||
|
|
||
| initExtensionPoints(); | ||
| } | ||
|
|
||
| private void initExtensionPoints() | ||
| { | ||
| Plugin phpCorePlugin = PHPEplPlugin.getDefault(); | ||
| if (phpCorePlugin == null) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor( | ||
| IPHPCoreEPLConstants.PLUGIN_ID, IPHPCoreEPLConstants.IP_VARIABLE_INITIALIZER_EXTPOINT_ID); | ||
| for (IConfigurationElement element : elements) | ||
| { | ||
| if ("variable".equals(element.getName())) { //$NON-NLS-1$ | ||
| String name = element.getAttribute("name"); //$NON-NLS-1$ | ||
| String value = element.getAttribute("value"); //$NON-NLS-1$ | ||
| // if (element.getAttribute("initializer") != null) { //$NON-NLS-1$ | ||
| // try { | ||
| // IIncludePathVariableInitializer initializer = (IIncludePathVariableInitializer) element.createExecutableExtension("initializer"); //$NON-NLS-1$ | ||
| // value = initializer.initialize(name); | ||
| // } catch (CoreException e) { | ||
| // Logger.logException(e); | ||
| // } | ||
| // } | ||
| // FIXME | ||
| if (value != null) | ||
| { | ||
| putVariable(name, new Path(value)); | ||
| reservedVariables.add(name); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| public synchronized void putVariable(String name, IPath path) | ||
| { | ||
| this.variables.put(name, path); | ||
| } | ||
|
|
||
| /** | ||
| * Returns <code>true</code> if the specified variable is reserved | ||
| * | ||
| * @param variableName | ||
| * Variable name | ||
| */ | ||
| public boolean isReserved(String variableName) | ||
| { | ||
| return reservedVariables.contains(variableName); | ||
| } | ||
|
|
||
| public String[] getReservedVariables() | ||
| { | ||
| return (String[]) reservedVariables.toArray(new String[reservedVariables.size()]); | ||
| } | ||
|
|
||
| /** | ||
| * Returns resolved IPath from the given path string that starts from include path variable | ||
| * | ||
| * @param path | ||
| * Path string | ||
| * @return resolved IPath or <code>null</code> if it couldn't be resolved | ||
| */ | ||
| public IPath resolveVariablePath(String path) | ||
| { | ||
| int index = path.indexOf('/'); | ||
| if (index != -1) | ||
| { | ||
| String var = path.substring(0, index); | ||
| IPath varPath = getIncludePathVariable(var); | ||
| if (varPath != null && index + 1 < path.length()) | ||
| { | ||
| varPath = varPath.append(path.substring(index + 1)); | ||
| } | ||
| return varPath; | ||
| } | ||
| return getIncludePathVariable(path); | ||
| } | ||
| } |
| @@ -0,0 +1,14 @@ | ||
| /** | ||
| * Copyright (c) 2006 Zend Technologies | ||
| * | ||
| */ | ||
| package org.eclipse.php.internal.core.project.options.includepath; | ||
|
|
||
| import org.eclipse.core.runtime.IPath; | ||
|
|
||
| public interface IncludePathVariablesListener | ||
| { | ||
|
|
||
| void includePathVariablesChanged(String[] names, IPath[] paths); | ||
|
|
||
| } |
| @@ -0,0 +1,36 @@ | ||
| /******************************************************************************* | ||
| * Copyright (c) 2006 Zend Corporation and IBM Corporation. | ||
| * All rights reserved. This program and the accompanying materials | ||
| * are made available under the terms of the Eclipse Public License v1.0 | ||
| * which accompanies this distribution, and is available at | ||
| * http://www.eclipse.org/legal/epl-v10.html | ||
| * | ||
| * Contributors: | ||
| * Zend and IBM - Initial implementation | ||
| *******************************************************************************/ | ||
| package org.eclipse.php.internal.core.util.preferences; | ||
|
|
||
| import java.util.Map; | ||
|
|
||
| /** | ||
| * The IXMLPreferencesStorable should be implemented by any class that should save or load its properties as XML. This | ||
| * class works with the XMLPreferencesWriter and XMLPreferencesReader. | ||
| */ | ||
| public interface IXMLPreferencesStorable | ||
| { | ||
|
|
||
| /** | ||
| * Returns hash map, that represent this object. | ||
| * | ||
| * @return HashMap | ||
| */ | ||
| public Map storeToMap(); | ||
|
|
||
| /** | ||
| * Restores the object from the map. | ||
| * | ||
| * @param HashMap | ||
| * map | ||
| */ | ||
| public void restoreFromMap(Map map); | ||
| } |
| @@ -0,0 +1,165 @@ | ||
| /******************************************************************************* | ||
| * Copyright (c) 2006 Zend Corporation and IBM Corporation. | ||
| * All rights reserved. This program and the accompanying materials | ||
| * are made available under the terms of the Eclipse Public License v1.0 | ||
| * which accompanies this distribution, and is available at | ||
| * http://www.eclipse.org/legal/epl-v10.html | ||
| * | ||
| * Contributors: | ||
| * Zend and IBM - Initial implementation | ||
| *******************************************************************************/ | ||
| package org.eclipse.php.internal.core.util.preferences; | ||
|
|
||
| import java.io.ByteArrayInputStream; | ||
| import java.util.ArrayList; | ||
| import java.util.HashMap; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.StringTokenizer; | ||
|
|
||
| import javax.xml.parsers.DocumentBuilder; | ||
| import javax.xml.parsers.DocumentBuilderFactory; | ||
|
|
||
| import org.eclipse.core.resources.ProjectScope; | ||
| import org.eclipse.core.runtime.Preferences; | ||
| import org.eclipse.jface.preference.IPreferenceStore; | ||
| import org.eclipse.ui.preferences.IWorkingCopyManager; | ||
| import org.w3c.dom.Document; | ||
| import org.w3c.dom.Node; | ||
| import org.w3c.dom.NodeList; | ||
|
|
||
| import com.aptana.core.util.StringUtil; | ||
| import com.aptana.core.util.replace.SimpleTextPatternReplacer; | ||
| import com.aptana.editor.php.epl.PHPEplPlugin; | ||
| import com.aptana.editor.php.util.Key; | ||
|
|
||
| /** | ||
| * XML preferences reader for reading XML structures from the preferences store. This class works in combination with | ||
| * IXMLPreferencesStorable. | ||
| */ | ||
| public class XMLPreferencesReader | ||
| { | ||
|
|
||
| public static final char DELIMITER = (char) 5; | ||
| private static final SimpleTextPatternReplacer TAG_REPLACER = new SimpleTextPatternReplacer(); | ||
| static | ||
| { | ||
| TAG_REPLACER.addPattern("&", "&"); //$NON-NLS-1$ //$NON-NLS-2$ | ||
| TAG_REPLACER.addPattern("'", "'"); //$NON-NLS-1$ //$NON-NLS-2$ | ||
| TAG_REPLACER.addPattern(""", "\""); //$NON-NLS-1$ //$NON-NLS-2$ | ||
| TAG_REPLACER.addPattern("<", "<"); //$NON-NLS-1$ //$NON-NLS-2$ | ||
| TAG_REPLACER.addPattern(">", ">"); //$NON-NLS-1$ //$NON-NLS-2$ | ||
| } | ||
| public static final String STRING_DEFAULT = StringUtil.EMPTY; | ||
|
|
||
| public static String getUnEscaped(String s) | ||
| { | ||
| return TAG_REPLACER.searchAndReplace(s); | ||
| } | ||
|
|
||
| private static Map read(NodeList nl) | ||
| { | ||
| Map map = new HashMap(nl.getLength()); | ||
| for (int i = 0; i < nl.getLength(); ++i) | ||
| { | ||
| Node n = nl.item(i); | ||
| if (n.hasChildNodes()) | ||
| { | ||
| if (n.getFirstChild().getNodeType() == Node.TEXT_NODE) | ||
| { | ||
| map.put(n.getNodeName(), getUnEscaped(n.getFirstChild().getNodeValue())); | ||
| } | ||
| else | ||
| { | ||
| map.put(n.getNodeName(), read(n.getChildNodes())); | ||
| } | ||
| } | ||
| } | ||
| return map; | ||
| } | ||
|
|
||
| private static Map read(String str) | ||
| { | ||
| try | ||
| { | ||
| DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); | ||
| // docBuilderFactory.setValidating(true); | ||
| DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); | ||
| Document doc = docBuilder.parse(new ByteArrayInputStream(str.getBytes())); | ||
|
|
||
| return read(doc.getChildNodes()); | ||
|
|
||
| } | ||
| catch (Exception e) | ||
| { | ||
| PHPEplPlugin.logError("Unexpected exception", e); | ||
| } | ||
| return null; | ||
| } | ||
|
|
||
| /** | ||
| * Reads a map of elements from the IPreferenceStore by a given key. | ||
| * | ||
| * @param store | ||
| * @param prefsKey | ||
| * @return | ||
| */ | ||
| public static Map[] read(IPreferenceStore store, String prefsKey) | ||
| { | ||
| List<Map<?, ?>> maps = new ArrayList<Map<?, ?>>(); | ||
| StringTokenizer st = new StringTokenizer(store.getString(prefsKey), new String(new char[] { DELIMITER })); | ||
| while (st.hasMoreTokens()) | ||
| { | ||
| maps.add(read(st.nextToken())); | ||
| } | ||
| return maps.toArray(new HashMap[maps.size()]); | ||
| } | ||
|
|
||
| /** | ||
| * Reads a map of elements from the Preferences by a given key. | ||
| * | ||
| * @param store | ||
| * @param prefsKey | ||
| * @return | ||
| */ | ||
| public static Map[] read(Preferences store, String prefsKey) | ||
| { | ||
| String storedValue = store.getString(prefsKey); | ||
| return getHashFromStoredValue(storedValue); | ||
| } | ||
|
|
||
| /** | ||
| * Reads a map of elements from the project Properties by a given key. | ||
| * | ||
| * @param prefsKey | ||
| * The key to store by. | ||
| * @param projectScope | ||
| * The context for the project Scope | ||
| * @param workingCopyManager | ||
| * @return | ||
| */ | ||
| public static Map[] read(Key prefKey, ProjectScope projectScope, IWorkingCopyManager workingCopyManager) | ||
| { | ||
|
|
||
| String storedValue = prefKey.getStoredValue(projectScope, workingCopyManager); | ||
| if (storedValue == null) | ||
| { | ||
| storedValue = STRING_DEFAULT; | ||
| } | ||
| return getHashFromStoredValue(storedValue); | ||
|
|
||
| } | ||
|
|
||
| public static Map[] getHashFromStoredValue(String storedValue) | ||
| { | ||
|
|
||
| List<Map> maps = new ArrayList<Map>(); | ||
| StringTokenizer st = new StringTokenizer(storedValue, new String(new char[] { DELIMITER })); | ||
| while (st.hasMoreTokens()) | ||
| { | ||
| maps.add(read(st.nextToken())); | ||
| } | ||
| return maps.toArray(new HashMap[maps.size()]); | ||
|
|
||
| } | ||
| } |
| @@ -0,0 +1,223 @@ | ||
| /******************************************************************************* | ||
| * Copyright (c) 2006 Zend Corporation and IBM Corporation. | ||
| * All rights reserved. This program and the accompanying materials | ||
| * are made available under the terms of the Eclipse Public License v1.0 | ||
| * which accompanies this distribution, and is available at | ||
| * http://www.eclipse.org/legal/epl-v10.html | ||
| * | ||
| * Contributors: | ||
| * Zend and IBM - Initial implementation | ||
| *******************************************************************************/ | ||
| package org.eclipse.php.internal.core.util.preferences; | ||
|
|
||
| import java.util.Iterator; | ||
| import java.util.Map; | ||
| import java.util.Set; | ||
|
|
||
| import org.eclipse.core.resources.ProjectScope; | ||
| import org.eclipse.core.runtime.Plugin; | ||
| import org.eclipse.core.runtime.Preferences; | ||
| import org.eclipse.jface.preference.IPreferenceStore; | ||
| import org.eclipse.ui.preferences.IWorkingCopyManager; | ||
|
|
||
| import com.aptana.editor.php.util.Key; | ||
|
|
||
| /** | ||
| * XML preferences writer for writing XML structures into the prefernces store. This class works in combination with | ||
| * IXMLPreferencesStorable. | ||
| */ | ||
| public class XMLPreferencesWriter | ||
| { | ||
|
|
||
| public static final char DELIMITER = (char) 5; | ||
|
|
||
| public static String getEscaped(String s) | ||
| { | ||
| StringBuilder result = new StringBuilder(s.length() + 10); | ||
| for (int i = 0; i < s.length(); ++i) | ||
| { | ||
| appendEscapedChar(result, s.charAt(i)); | ||
| } | ||
| return result.toString(); | ||
| } | ||
|
|
||
| private static void appendEscapedChar(StringBuilder buffer, char c) | ||
| { | ||
| String replacement = getReplacement(c); | ||
| if (replacement != null) | ||
| { | ||
| buffer.append('&'); | ||
| buffer.append(replacement); | ||
| buffer.append(';'); | ||
| } | ||
| else | ||
| { | ||
| buffer.append(c); | ||
| } | ||
| } | ||
|
|
||
| private static String getReplacement(char c) | ||
| { | ||
| // Encode special XML characters into the equivalent character references. | ||
| // These five are defined by default for all XML documents. | ||
| switch (c) | ||
| { | ||
| case '<': | ||
| return "lt"; //$NON-NLS-1$ | ||
| case '>': | ||
| return "gt"; //$NON-NLS-1$ | ||
| case '"': | ||
| return "quot"; //$NON-NLS-1$ | ||
| case '\'': | ||
| return "apos"; //$NON-NLS-1$ | ||
| case '&': | ||
| return "amp"; //$NON-NLS-1$ | ||
| } | ||
| return null; | ||
| } | ||
|
|
||
| @SuppressWarnings("rawtypes") | ||
| private static void write(StringBuilder sb, Map map) | ||
| { | ||
| Set keys = map.keySet(); | ||
| for (Iterator i = keys.iterator(); i.hasNext();) | ||
| { | ||
| String key = (String) i.next(); | ||
| sb.append("<"); //$NON-NLS-1$ | ||
| sb.append(key); | ||
| sb.append(">"); //$NON-NLS-1$ | ||
| Object object = map.get(key); | ||
| if (object instanceof Map) | ||
| { | ||
| write(sb, (Map) object); | ||
| } | ||
| else | ||
| { | ||
| if (object != null) | ||
| { | ||
| sb.append(getEscaped(object.toString())); | ||
| } | ||
| else | ||
| { | ||
| sb.append(""); //$NON-NLS-1$ | ||
| } | ||
| } | ||
| sb.append("</"); //$NON-NLS-1$ | ||
| sb.append(key); | ||
| sb.append(">"); //$NON-NLS-1$ | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Writes a group of IXMLPreferencesStorables to the given the project properties. | ||
| * | ||
| * @param prefsKey | ||
| * The key to store by. | ||
| * @param objects | ||
| * The IXMLPreferencesStorables to store. | ||
| * @param projectScope | ||
| * The project Scope | ||
| * @param workingCopyManager | ||
| */ | ||
| public static void write(Key prefsKey, IXMLPreferencesStorable[] objects, ProjectScope projectScope, | ||
| IWorkingCopyManager workingCopyManager) | ||
| { | ||
| StringBuilder sb = new StringBuilder(); | ||
| appendDelimitedString(sb, objects); | ||
| prefsKey.setStoredValue(projectScope, sb.toString(), workingCopyManager); | ||
|
|
||
| } | ||
|
|
||
| /** | ||
| * Writes an IXMLPreferencesStorables to the given IPreferenceStore. | ||
| * | ||
| * @param store | ||
| * An IPreferenceStore instance | ||
| * @param prefsKey | ||
| * The key to store by. | ||
| * @param object | ||
| * The IXMLPreferencesStorables to store. | ||
| */ | ||
| public static void write(IPreferenceStore store, String prefsKey, IXMLPreferencesStorable object) | ||
| { | ||
| StringBuilder sb = new StringBuilder(); | ||
| write(sb, object.storeToMap()); | ||
| store.setValue(prefsKey, sb.toString()); | ||
| } | ||
|
|
||
| /** | ||
| * Writes a group of IXMLPreferencesStorables to the given IPreferenceStore. | ||
| * | ||
| * @param store | ||
| * An IPreferenceStore instance | ||
| * @param prefsKey | ||
| * The key to store by. | ||
| * @param objects | ||
| * The IXMLPreferencesStorables to store. | ||
| */ | ||
| public static void write(IPreferenceStore store, String prefsKey, IXMLPreferencesStorable[] objects) | ||
| { | ||
| StringBuilder sb = new StringBuilder(); | ||
| appendDelimitedString(sb, objects); | ||
| store.setValue(prefsKey, sb.toString()); | ||
| } | ||
|
|
||
| /** | ||
| * Writes a group of IXMLPreferencesStorables to the given plugin preferences. The caller to this method should also | ||
| * make sure that {@link Plugin#savePluginPreferences()} is called in order to really store the changes. | ||
| * | ||
| * @param pluginPreferences | ||
| * A Preferences instance | ||
| * @param prefsKey | ||
| * The key to store by. | ||
| * @param objects | ||
| * The IXMLPreferencesStorables to store. | ||
| */ | ||
| public static void write(Preferences pluginPreferences, String prefsKey, IXMLPreferencesStorable[] objects) | ||
| { | ||
| StringBuilder sb = new StringBuilder(); | ||
| appendDelimitedString(sb, objects); | ||
| pluginPreferences.setValue(prefsKey, sb.toString()); | ||
| } | ||
|
|
||
| /** | ||
| * Writes an IXMLPreferencesStorable to the given plugin preferences. The caller to this method should also make | ||
| * sure that {@link Plugin#savePluginPreferences()} is called in order to really store the changes. | ||
| * | ||
| * @param pluginPreferences | ||
| * A Preferences instance | ||
| * @param prefsKey | ||
| * The key to store by. | ||
| * @param object | ||
| * The IXMLPreferencesStorable to store. | ||
| */ | ||
| public static void write(Preferences pluginPreferences, String prefsKey, IXMLPreferencesStorable object) | ||
| { | ||
| StringBuilder sb = new StringBuilder(); | ||
| write(sb, object.storeToMap()); | ||
| pluginPreferences.setValue(prefsKey, sb.toString()); | ||
| } | ||
|
|
||
| // Append the elements one by one into the given StringBuffer. | ||
| private static void appendDelimitedString(StringBuilder buffer, IXMLPreferencesStorable[] elements) | ||
| { | ||
| if (elements != null) | ||
| { | ||
| for (int i = 0; i < elements.length; ++i) | ||
| { | ||
| write(buffer, elements[i].storeToMap()); | ||
| if (i < elements.length - 1) | ||
| { | ||
| buffer.append(DELIMITER); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| public static String storableElementsToString(IXMLPreferencesStorable[] elements) | ||
| { | ||
| StringBuilder sb = new StringBuilder(); | ||
| appendDelimitedString(sb, elements); | ||
| return sb.toString(); | ||
| } | ||
| } |
| @@ -0,0 +1,160 @@ | ||
| /******************************************************************************* | ||
| * Copyright (c) 2000, 2007 IBM Corporation and others. | ||
| * All rights reserved. This program and the accompanying materials | ||
| * are made available under the terms of the Eclipse Public License v1.0 | ||
| * which accompanies this distribution, and is available at | ||
| * http://www.eclipse.org/legal/epl-v10.html | ||
| * | ||
| * Contributors: | ||
| * IBM Corporation - initial API and implementation | ||
| *******************************************************************************/ | ||
| package org.eclipse.php.internal.ui.util; | ||
|
|
||
| import org.eclipse.core.runtime.Assert; | ||
| import org.eclipse.jface.dialogs.IDialogConstants; | ||
| import org.eclipse.jface.resource.JFaceResources; | ||
| 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.Label; | ||
| import org2.eclipse.php.internal.ui.util.PixelConverter; | ||
|
|
||
| /** | ||
| * Factory class to create some SWT resources. | ||
| */ | ||
| public class SWTFactory | ||
| { | ||
|
|
||
| /** | ||
| * Returns a width hint for a button control. | ||
| */ | ||
| public static int getButtonWidthHint(Button button) | ||
| { | ||
| button.setFont(JFaceResources.getDialogFont()); | ||
| PixelConverter converter = new PixelConverter(button); | ||
| int widthHint = converter.convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH); | ||
| return Math.max(widthHint, button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x); | ||
| } | ||
|
|
||
| /** | ||
| * 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).widthHint = getButtonWidthHint(button); | ||
| ((GridData) gd).horizontalAlignment = GridData.FILL; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Creates and returns a new push button with the given label and/or image. | ||
| * | ||
| * @param parent | ||
| * parent control | ||
| * @param label | ||
| * button label or <code>null</code> | ||
| * @param image | ||
| * image of <code>null</code> | ||
| * @return a new push button | ||
| */ | ||
| public static Button createPushButton(Composite parent, String label, Image image) | ||
| { | ||
| Button button = new Button(parent, SWT.PUSH); | ||
| button.setFont(parent.getFont()); | ||
| if (image != null) | ||
| { | ||
| button.setImage(image); | ||
| } | ||
| if (label != null) | ||
| { | ||
| button.setText(label); | ||
| } | ||
| GridData gd = new GridData(); | ||
| button.setLayoutData(gd); | ||
| SWTFactory.setButtonDimensionHint(button); | ||
| return button; | ||
| } | ||
|
|
||
| /** | ||
| * Creates a new label widget | ||
| * | ||
| * @param parent | ||
| * the parent composite to add this label widget to | ||
| * @param text | ||
| * the text for the label | ||
| * @param hspan | ||
| * the horizontal span to take up in the parent composite | ||
| * @return the new label | ||
| * @since 3.2 | ||
| */ | ||
| public static Label createLabel(Composite parent, String text, int hspan) | ||
| { | ||
| Label l = new Label(parent, SWT.NONE); | ||
| l.setFont(parent.getFont()); | ||
| l.setText(text); | ||
| GridData gd = new GridData(GridData.FILL_HORIZONTAL); | ||
| gd.horizontalSpan = hspan; | ||
| gd.grabExcessHorizontalSpace = false; | ||
| l.setLayoutData(gd); | ||
| return l; | ||
| } | ||
|
|
||
| /** | ||
| * Creates a wrapping label | ||
| * | ||
| * @param parent | ||
| * the parent composite to add this label to | ||
| * @param text | ||
| * the text to be displayed in the label | ||
| * @param hspan | ||
| * the horizontal span that label should take up in the parent composite | ||
| * @return a new label that wraps at a specified width | ||
| * @since 3.3 | ||
| */ | ||
| public static Label createWrapLabel(Composite parent, String text, int hspan) | ||
| { | ||
| Label l = new Label(parent, SWT.NONE | SWT.WRAP); | ||
| l.setFont(parent.getFont()); | ||
| l.setText(text); | ||
| GridData gd = new GridData(GridData.FILL_HORIZONTAL); | ||
| gd.horizontalSpan = hspan; | ||
| l.setLayoutData(gd); | ||
| return l; | ||
| } | ||
|
|
||
| /** | ||
| * Creates a composite that uses the parent's font and has a grid layout | ||
| * | ||
| * @param parent | ||
| * the parent to add the composite to | ||
| * @param columns | ||
| * the number of columns the composite should have | ||
| * @param hspan | ||
| * the horizontal span the new composite should take up in the parent | ||
| * @param fill | ||
| * the fill style of the composite {@link GridData} | ||
| * @return a new composite with a grid layout | ||
| * @since 3.3 | ||
| */ | ||
| public static Composite createComposite(Composite parent, int columns, int hspan, int fill) | ||
| { | ||
| Composite g = new Composite(parent, SWT.NONE); | ||
| g.setLayout(new GridLayout(columns, false)); | ||
| g.setFont(parent.getFont()); | ||
| GridData gd = new GridData(fill); | ||
| gd.horizontalSpan = hspan; | ||
| g.setLayoutData(gd); | ||
| return g; | ||
| } | ||
| } |
| @@ -0,0 +1,26 @@ | ||
| /******************************************************************************* | ||
| * Copyright (c) 2006 Zend Corporation and IBM Corporation. | ||
| * All rights reserved. This program and the accompanying materials | ||
| * are made available under the terms of the Eclipse Public License v1.0 | ||
| * which accompanies this distribution, and is available at | ||
| * http://www.eclipse.org/legal/epl-v10.html | ||
| * | ||
| * Contributors: | ||
| * Zend and IBM - Initial implementation | ||
| *******************************************************************************/ | ||
| package org.eclipse.php.internal.ui.wizard.field; | ||
|
|
||
| import org2.eclipse.php.internal.ui.wizard.field.DialogField; | ||
|
|
||
| /** | ||
| * Change listener used by <code>StringButtonDialogField</code> | ||
| */ | ||
| public interface IStringButtonAdapter | ||
| { | ||
|
|
||
| /** | ||
| * @param field | ||
| */ | ||
| void changeControlPressed(DialogField field); | ||
|
|
||
| } |
| @@ -0,0 +1,175 @@ | ||
| /******************************************************************************* | ||
| * Copyright (c) 2000, 2011 IBM Corporation and others. | ||
| * All rights reserved. This program and the accompanying materials | ||
| * are made available under the terms of the Eclipse Public License v1.0 | ||
| * which accompanies this distribution, and is available at | ||
| * http://www.eclipse.org/legal/epl-v10.html | ||
| * | ||
| * Contributors: | ||
| * IBM Corporation - initial API and implementation | ||
| *******************************************************************************/ | ||
| package org.eclipse.php.internal.ui.wizard.field; | ||
|
|
||
| import org.eclipse.swt.SWT; | ||
| import org.eclipse.swt.events.SelectionEvent; | ||
| import org.eclipse.swt.events.SelectionListener; | ||
| import org.eclipse.swt.layout.GridData; | ||
| 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.Text; | ||
| import org2.eclipse.php.internal.ui.wizard.field.DialogField; | ||
| import org2.eclipse.php.util.SWTUtil; | ||
|
|
||
| /** | ||
| * Dialog field containing a label, text control and a button control. | ||
| */ | ||
| public class StringButtonDialogField extends StringDialogField | ||
| { | ||
|
|
||
| private Button fBrowseButton; | ||
| private String fBrowseButtonLabel; | ||
| private IStringButtonAdapter fStringButtonAdapter; | ||
|
|
||
| private boolean fButtonEnabled; | ||
|
|
||
| /** | ||
| * @param adapter | ||
| */ | ||
| public StringButtonDialogField(IStringButtonAdapter adapter) | ||
| { | ||
| super(); | ||
| fStringButtonAdapter = adapter; | ||
| fBrowseButtonLabel = "!Browse...!"; //$NON-NLS-1$ | ||
| fButtonEnabled = true; | ||
| } | ||
|
|
||
| /** | ||
| * Sets the label of the button. | ||
| * | ||
| * @param label | ||
| */ | ||
| public void setButtonLabel(String label) | ||
| { | ||
| fBrowseButtonLabel = label; | ||
| } | ||
|
|
||
| // ------ adapter communication | ||
|
|
||
| /** | ||
| * Programmatical pressing of the button | ||
| */ | ||
| public void changeControlPressed() | ||
| { | ||
| fStringButtonAdapter.changeControlPressed(this); | ||
| } | ||
|
|
||
| // ------- layout helpers | ||
|
|
||
| /** | ||
| * @param parent | ||
| * @param nColumns | ||
| * @return controls | ||
| */ | ||
| public Control[] doFillIntoGrid(Composite parent, int nColumns) | ||
| { | ||
| assertEnoughColumns(nColumns); | ||
|
|
||
| Label label = getLabelControl(parent); | ||
| label.setLayoutData(gridDataForLabel(1)); | ||
| Text text = getTextControl(parent); | ||
| text.setLayoutData(gridDataForText(nColumns - 2)); | ||
| Button button = getChangeControl(parent); | ||
| button.setLayoutData(gridDataForButton(button, 1)); | ||
|
|
||
| return new Control[] { label, text, button }; | ||
| } | ||
|
|
||
| /** | ||
| * @return number of controls | ||
| */ | ||
| public int getNumberOfControls() | ||
| { | ||
| return 3; | ||
| } | ||
|
|
||
| /** | ||
| * @param button | ||
| * @param span | ||
| * @return | ||
| */ | ||
| protected static GridData gridDataForButton(Button button, int span) | ||
| { | ||
| GridData gd = new GridData(); | ||
| gd.horizontalAlignment = GridData.END; | ||
| gd.grabExcessHorizontalSpace = false; | ||
| gd.horizontalSpan = span; | ||
| gd.widthHint = SWTUtil.getButtonWidthHint(button); | ||
| return gd; | ||
| } | ||
|
|
||
| // ------- ui creation | ||
|
|
||
| /** | ||
| * Creates or returns the created buttom widget. | ||
| * | ||
| * @param parent | ||
| * The parent composite or <code>null</code> if the widget has already been created. | ||
| * @return button | ||
| */ | ||
| public Button getChangeControl(Composite parent) | ||
| { | ||
| if (fBrowseButton == null) | ||
| { | ||
| assertCompositeNotNull(parent); | ||
|
|
||
| fBrowseButton = new Button(parent, SWT.PUSH); | ||
| fBrowseButton.setFont(parent.getFont()); | ||
| fBrowseButton.setText(fBrowseButtonLabel); | ||
| fBrowseButton.setEnabled(isEnabled() && fButtonEnabled); | ||
| fBrowseButton.addSelectionListener(new SelectionListener() | ||
| { | ||
| public void widgetDefaultSelected(SelectionEvent e) | ||
| { | ||
| changeControlPressed(); | ||
| } | ||
|
|
||
| public void widgetSelected(SelectionEvent e) | ||
| { | ||
| changeControlPressed(); | ||
| } | ||
| }); | ||
|
|
||
| } | ||
| return fBrowseButton; | ||
| } | ||
|
|
||
| // ------ enable / disable management | ||
|
|
||
| /** | ||
| * Sets the enable state of the button. | ||
| * | ||
| * @param enable | ||
| */ | ||
| public void enableButton(boolean enable) | ||
| { | ||
| if (isOkToUse(fBrowseButton)) | ||
| { | ||
| fBrowseButton.setEnabled(isEnabled() && enable); | ||
| } | ||
| fButtonEnabled = enable; | ||
| } | ||
|
|
||
| /** | ||
| * @see DialogField#updateEnableState | ||
| */ | ||
| protected void updateEnableState() | ||
| { | ||
| super.updateEnableState(); | ||
| if (isOkToUse(fBrowseButton)) | ||
| { | ||
| fBrowseButton.setEnabled(isEnabled() && fButtonEnabled); | ||
| } | ||
| } | ||
| } |
| @@ -0,0 +1,295 @@ | ||
| /******************************************************************************* | ||
| * Copyright (c) 2000, 2005 IBM Corporation and others. | ||
| * All rights reserved. This program and the accompanying materials | ||
| * are made available under the terms of the Eclipse Public License v1.0 | ||
| * which accompanies this distribution, and is available at | ||
| * http://www.eclipse.org/legal/epl-v10.html | ||
| * | ||
| * Contributors: | ||
| * IBM Corporation - initial API and implementation | ||
| *******************************************************************************/ | ||
| package org.eclipse.php.internal.ui.wizard.field; | ||
|
|
||
| import org.eclipse.jface.bindings.keys.KeyStroke; | ||
| import org.eclipse.jface.fieldassist.ContentProposalAdapter; | ||
| import org.eclipse.jface.fieldassist.DecoratedField; | ||
| import org.eclipse.jface.fieldassist.FieldDecoration; | ||
| import org.eclipse.jface.fieldassist.FieldDecorationRegistry; | ||
| import org.eclipse.jface.fieldassist.IContentProposalProvider; | ||
| import org.eclipse.jface.fieldassist.IControlCreator; | ||
| import org.eclipse.jface.fieldassist.TextContentAdapter; | ||
| import org.eclipse.jface.viewers.LabelProvider; | ||
| import org.eclipse.swt.SWT; | ||
| import org.eclipse.swt.events.ModifyEvent; | ||
| import org.eclipse.swt.events.ModifyListener; | ||
| import org.eclipse.swt.layout.GridData; | ||
| import org.eclipse.swt.widgets.Composite; | ||
| import org.eclipse.swt.widgets.Control; | ||
| import org.eclipse.swt.widgets.Label; | ||
| import org.eclipse.swt.widgets.Text; | ||
| import org2.eclipse.php.internal.ui.wizard.field.DialogField; | ||
|
|
||
| import com.aptana.core.util.StringUtil; | ||
|
|
||
| /** | ||
| * Dialog field containing a label and a text control. | ||
| */ | ||
| public class StringDialogField extends DialogField | ||
| { | ||
|
|
||
| protected String fText; | ||
| protected Text fTextControl; | ||
| protected ModifyListener fModifyListener; | ||
| protected IContentProposalProvider fContentAssistProcessor; | ||
| protected ContentProposalAdapter contentProposalAdapter; | ||
| protected LabelProvider labelProvider; | ||
|
|
||
| /** | ||
| * @param labelProvider | ||
| */ | ||
| public void setContentAssistLabelProvider(LabelProvider labelProvider) | ||
| { | ||
| this.labelProvider = labelProvider; | ||
| } | ||
|
|
||
| /** | ||
| * @return current content proposal provider | ||
| */ | ||
| public IContentProposalProvider getFContentAssistProcessor() | ||
| { | ||
| return fContentAssistProcessor; | ||
| } | ||
|
|
||
| /** | ||
| * @param contentAssistProcessor | ||
| */ | ||
| public void setFContentAssistProcessor(IContentProposalProvider contentAssistProcessor) | ||
| { | ||
| fContentAssistProcessor = contentAssistProcessor; | ||
| } | ||
|
|
||
| /** | ||
| * | ||
| */ | ||
| public StringDialogField() | ||
| { | ||
| super(); | ||
| fText = StringUtil.EMPTY; | ||
| } | ||
|
|
||
| /** | ||
| * @see DialogField#doFillIntoGrid(org.eclipse.swt.widgets.Composite, int) | ||
| */ | ||
| // ------- layout helpers | ||
| /* | ||
| * @see DialogField#doFillIntoGrid | ||
| */ | ||
| public Control[] doFillIntoGrid(Composite parent, int nColumns) | ||
| { | ||
| assertEnoughColumns(nColumns); | ||
|
|
||
| Label label = getLabelControl(parent); | ||
| label.setLayoutData(gridDataForLabel(1)); | ||
| Text text = getTextControl(parent); | ||
| text.setLayoutData(gridDataForText(nColumns - 1)); | ||
|
|
||
| return new Control[] { label, text }; | ||
| } | ||
|
|
||
| /* | ||
| * @see DialogField#getNumberOfControls | ||
| */ | ||
| /** | ||
| * @see DialogField#getNumberOfControls() | ||
| */ | ||
| public int getNumberOfControls() | ||
| { | ||
| return 2; | ||
| } | ||
|
|
||
| /** | ||
| * @param span | ||
| * @return GridData | ||
| */ | ||
| protected static GridData gridDataForText(int span) | ||
| { | ||
| GridData gd = new GridData(); | ||
| gd.horizontalAlignment = GridData.FILL; | ||
| gd.grabExcessHorizontalSpace = false; | ||
| gd.horizontalSpan = span; | ||
| return gd; | ||
| } | ||
|
|
||
| // ------- focus methods | ||
|
|
||
| /* | ||
| * @see DialogField#setFocus | ||
| */ | ||
| /** | ||
| * @see DialogField#setFocus() | ||
| */ | ||
| public boolean setFocus() | ||
| { | ||
| if (isOkToUse(fTextControl)) | ||
| { | ||
| fTextControl.setFocus(); | ||
| fTextControl.setSelection(0, fTextControl.getText().length()); | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| // ------- ui creation | ||
|
|
||
| /** | ||
| * Creates or returns the created text control. | ||
| * | ||
| * @param parent | ||
| * The parent composite or <code>null</code> when the widget has already been created. | ||
| * @return Text | ||
| */ | ||
| public Text getTextControl(Composite parent) | ||
| { | ||
| if (fContentAssistProcessor != null) | ||
| { | ||
| DecoratedField fld = new DecoratedField(parent, SWT.NONE, new IControlCreator() | ||
| { | ||
|
|
||
| public Control createControl(Composite parent, int style) | ||
| { | ||
| createText(parent); | ||
| return fTextControl; | ||
| } | ||
|
|
||
| }); | ||
| FieldDecoration fieldDecoration = FieldDecorationRegistry.getDefault().getFieldDecoration( | ||
| FieldDecorationRegistry.DEC_CONTENT_PROPOSAL); | ||
| fld.addFieldDecoration(fieldDecoration, SWT.TOP | SWT.LEFT, true); | ||
| fld.showDecoration(fieldDecoration); | ||
| final KeyStroke keyStroke = KeyStroke.getInstance(SWT.CONTROL, 32); | ||
|
|
||
| contentProposalAdapter = new ContentProposalAdapter(fTextControl, new TextContentAdapter(), | ||
| fContentAssistProcessor, keyStroke, null); | ||
| contentProposalAdapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE); | ||
| contentProposalAdapter.setLabelProvider(labelProvider); | ||
| return fTextControl; | ||
| } | ||
| createText(parent); | ||
| return fTextControl; | ||
| } | ||
|
|
||
| private void createText(Composite parent) | ||
| { | ||
| if (fTextControl == null) | ||
| { | ||
| assertCompositeNotNull(parent); | ||
| fModifyListener = new ModifyListener() | ||
| { | ||
| public void modifyText(ModifyEvent e) | ||
| { | ||
| doModifyText(e); | ||
| } | ||
| }; | ||
|
|
||
| fTextControl = new Text(parent, SWT.SINGLE | SWT.BORDER); | ||
| // moved up due to 1GEUNW2 | ||
| fTextControl.setText(fText); | ||
| fTextControl.setFont(parent.getFont()); | ||
| fTextControl.addModifyListener(fModifyListener); | ||
|
|
||
| fTextControl.setEnabled(isEnabled()); | ||
| // if (fContentAssistProcessor != null) | ||
| // { | ||
| // | ||
| // } | ||
| } | ||
| } | ||
|
|
||
| protected void doModifyText(ModifyEvent e) | ||
| { | ||
| if (isOkToUse(fTextControl)) | ||
| { | ||
| fText = fTextControl.getText(); | ||
| } | ||
| dialogFieldChanged(); | ||
| } | ||
|
|
||
| // ------ enable / disable management | ||
|
|
||
| /* | ||
| * @see DialogField#updateEnableState | ||
| */ | ||
| /** | ||
| * @see DialogField#updateEnableState() | ||
| */ | ||
| protected void updateEnableState() | ||
| { | ||
| super.updateEnableState(); | ||
| if (isOkToUse(fTextControl)) | ||
| { | ||
| fTextControl.setEnabled(isEnabled()); | ||
| } | ||
| } | ||
|
|
||
| // ------ text access | ||
|
|
||
| /** | ||
| * Gets the text. Can not be <code>null</code> | ||
| * | ||
| * @return String | ||
| */ | ||
| public String getText() | ||
| { | ||
| return fText; | ||
| } | ||
|
|
||
| /** | ||
| * Sets the text. Triggers a dialog-changed event. | ||
| * | ||
| * @param text | ||
| */ | ||
| public void setText(String text) | ||
| { | ||
| fText = text; | ||
| if (isOkToUse(fTextControl)) | ||
| { | ||
| fTextControl.setText(text); | ||
| } | ||
| else | ||
| { | ||
| dialogFieldChanged(); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Sets the text without triggering a dialog-changed event. | ||
| * | ||
| * @param text | ||
| */ | ||
| public void setTextWithoutUpdate(String text) | ||
| { | ||
| fText = text; | ||
| if (isOkToUse(fTextControl)) | ||
| { | ||
| fTextControl.removeModifyListener(fModifyListener); | ||
| fTextControl.setText(text); | ||
| fTextControl.addModifyListener(fModifyListener); | ||
| } | ||
| } | ||
|
|
||
| /* | ||
| * (non-Javadoc) | ||
| * @see org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField#refresh() | ||
| */ | ||
| /** | ||
| * @see DialogField#refresh() | ||
| */ | ||
| public void refresh() | ||
| { | ||
| super.refresh(); | ||
| if (isOkToUse(fTextControl)) | ||
| { | ||
| setTextWithoutUpdate(fText); | ||
| } | ||
| } | ||
|
|
||
| } |
| @@ -0,0 +1,128 @@ | ||
| <?xml version='1.0' encoding='UTF-8'?> | ||
| <!-- Schema file written by PDE --> | ||
| <schema targetNamespace="com.aptana.editor.php" xmlns="http://www.w3.org/2001/XMLSchema"> | ||
| <annotation> | ||
| <appinfo> | ||
| <meta.schema plugin="com.aptana.editor.php" id="phpTextHovers" name="PHP Text Hovers"/> | ||
| </appinfo> | ||
| <documentation> | ||
| Provides text hover support for the PHP editor. The best-match hover will be displayed when needed. | ||
| </documentation> | ||
| </annotation> | ||
|
|
||
| <element name="extension"> | ||
| <annotation> | ||
| <appinfo> | ||
| <meta.element /> | ||
| </appinfo> | ||
| </annotation> | ||
| <complexType> | ||
| <sequence minOccurs="0" maxOccurs="unbounded"> | ||
| <element ref="textHover"/> | ||
| </sequence> | ||
| <attribute name="point" type="string" use="required"> | ||
| <annotation> | ||
| <documentation> | ||
|
|
||
| </documentation> | ||
| </annotation> | ||
| </attribute> | ||
| <attribute name="id" type="string"> | ||
| <annotation> | ||
| <documentation> | ||
|
|
||
| </documentation> | ||
| </annotation> | ||
| </attribute> | ||
| <attribute name="name" type="string"> | ||
| <annotation> | ||
| <documentation> | ||
|
|
||
| </documentation> | ||
| <appinfo> | ||
| <meta.attribute translatable="true"/> | ||
| </appinfo> | ||
| </annotation> | ||
| </attribute> | ||
| </complexType> | ||
| </element> | ||
|
|
||
| <element name="textHover"> | ||
| <annotation> | ||
| <documentation> | ||
| PHP text hover | ||
| </documentation> | ||
| </annotation> | ||
| <complexType> | ||
| <attribute name="id" type="string" use="required"> | ||
| <annotation> | ||
| <documentation> | ||
|
|
||
| </documentation> | ||
| </annotation> | ||
| </attribute> | ||
| <attribute name="name" type="string"> | ||
| <annotation> | ||
| <documentation> | ||
|
|
||
| </documentation> | ||
| </annotation> | ||
| </attribute> | ||
| <attribute name="class" type="string" use="required"> | ||
| <annotation> | ||
| <documentation> | ||
| An instance of AbstractPHPTextHover | ||
| </documentation> | ||
| <appinfo> | ||
| <meta.attribute kind="java" basedOn="com.aptana.editor.php.internal.ui.hover.AbstractPHPTextHover:"/> | ||
| </appinfo> | ||
| </annotation> | ||
| </attribute> | ||
| <attribute name="activatePlugin" type="boolean" use="default" value="false"> | ||
| <annotation> | ||
| <documentation> | ||
|
|
||
| </documentation> | ||
| </annotation> | ||
| </attribute> | ||
| </complexType> | ||
| </element> | ||
|
|
||
| <annotation> | ||
| <appinfo> | ||
| <meta.section type="since"/> | ||
| </appinfo> | ||
| <documentation> | ||
| [Enter the first release in which this extension point appears.] | ||
| </documentation> | ||
| </annotation> | ||
|
|
||
| <annotation> | ||
| <appinfo> | ||
| <meta.section type="examples"/> | ||
| </appinfo> | ||
| <documentation> | ||
| [Enter extension point usage example here.] | ||
| </documentation> | ||
| </annotation> | ||
|
|
||
| <annotation> | ||
| <appinfo> | ||
| <meta.section type="apiinfo"/> | ||
| </appinfo> | ||
| <documentation> | ||
| [Enter API information here.] | ||
| </documentation> | ||
| </annotation> | ||
|
|
||
| <annotation> | ||
| <appinfo> | ||
| <meta.section type="implementation"/> | ||
| </appinfo> | ||
| <documentation> | ||
| [Enter information about supplied implementation of this extension point.] | ||
| </documentation> | ||
| </annotation> | ||
|
|
||
|
|
||
| </schema> |
| @@ -0,0 +1,187 @@ | ||
| /** | ||
| * Aptana Studio | ||
| * Copyright (c) 2005-2012 by Appcelerator, Inc. All Rights Reserved. | ||
| * Licensed under the terms of the Eclipse Public License (EPL). | ||
| * Please see the license-epl.html included with this distribution for details. | ||
| * Any modifications to this file must keep this entire header intact. | ||
| */ | ||
| package com.aptana.editor.php.internal.ui.hover; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| import org.eclipse.jface.action.ToolBarManager; | ||
| import org.eclipse.jface.text.IInformationControlCreator; | ||
| import org.eclipse.jface.text.IRegion; | ||
| import org.eclipse.jface.text.ITextHoverExtension; | ||
| import org.eclipse.jface.text.ITextViewer; | ||
| import org.eclipse.jface.text.information.IInformationProviderExtension2; | ||
| import org.eclipse.ui.IEditorPart; | ||
|
|
||
| import com.aptana.editor.common.hover.AbstractDocumentationHover; | ||
| import com.aptana.editor.common.hover.CustomBrowserInformationControl; | ||
| import com.aptana.editor.php.PHPEditorPlugin; | ||
|
|
||
| /** | ||
| * Best match hover information provider.<br> | ||
| * This provider will try several hover contributers until a valid information is retrieved. | ||
| * | ||
| * @author Shalom Gibly <sgibly@aptana.com> | ||
| */ | ||
| public class PHPBestMatchHover extends AbstractPHPTextHover | ||
| { | ||
| private static final String DEBUG_HOVER_ID = "com.aptana.php.debug.debugHover"; //$NON-NLS-1$ | ||
| private List<PHPTextHoverDescriptor> textHoverDescriptors; | ||
| private List<AbstractPHPTextHover> instantiatedTextHovers; | ||
| private AbstractPHPTextHover bestHover; | ||
|
|
||
| /** | ||
| * Constructs a new best match text hover. | ||
| */ | ||
| public PHPBestMatchHover() | ||
| { | ||
| this.textHoverDescriptors = PHPHoverRegistry.getInstance().getTextHoversDescriptors(); | ||
| this.instantiatedTextHovers = new ArrayList<AbstractPHPTextHover>(this.textHoverDescriptors.size()); | ||
| } | ||
|
|
||
| /* | ||
| * (non-Javadoc) | ||
| * @see | ||
| * com.aptana.editor.php.internal.ui.hover.AbstractPHPTextHover#getHoverInfo2(org.eclipse.jface.text.ITextViewer, | ||
| * org.eclipse.jface.text.IRegion) | ||
| */ | ||
| public Object getHoverInfo2(ITextViewer textViewer, IRegion hoverRegion) | ||
| { | ||
| checkHovers(); | ||
| for (AbstractPHPTextHover hover : instantiatedTextHovers) | ||
| { | ||
| hover.setEditor(getEditor()); | ||
| Object info = hover.getHoverInfo2(textViewer, hoverRegion); | ||
| if (info != null) | ||
| { | ||
| bestHover = hover; | ||
| return info; | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
|
|
||
| /* | ||
| * (non-Javadoc) | ||
| * @see org.eclipse.jface.text.ITextHover#getHoverInfo(org.eclipse.jface.text.ITextViewer, | ||
| * org.eclipse.jface.text.IRegion) | ||
| */ | ||
| public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) | ||
| { | ||
| Object info = getHoverInfo2(textViewer, hoverRegion); | ||
| if (info != null) | ||
| { | ||
| return info.toString(); | ||
| } | ||
| return null; | ||
| } | ||
|
|
||
| /* | ||
| * (non-Javadoc) | ||
| * @see com.aptana.editor.php.internal.ui.hover.AbstractPHPTextHover#getHoverControlCreator() | ||
| */ | ||
| public IInformationControlCreator getHoverControlCreator() | ||
| { | ||
| if (bestHover instanceof ITextHoverExtension) | ||
| { | ||
| return ((ITextHoverExtension) bestHover).getHoverControlCreator(); | ||
| } | ||
| return super.getHoverControlCreator(); | ||
| } | ||
|
|
||
| /* | ||
| * (non-Javadoc) | ||
| * @see com.aptana.editor.php.internal.ui.hover.AbstractPHPTextHover#getInformationPresenterControlCreator() | ||
| */ | ||
| public IInformationControlCreator getInformationPresenterControlCreator() | ||
| { | ||
| if (bestHover instanceof IInformationProviderExtension2) | ||
| { | ||
| return ((IInformationProviderExtension2) bestHover).getInformationPresenterControlCreator(); | ||
| } | ||
|
|
||
| return super.getInformationPresenterControlCreator(); | ||
| } | ||
|
|
||
| /** | ||
| * Check that we have instances of the text hovers. In case we don't have an instance for a descriptor that we have, | ||
| * we check if we can instantiate it, and then decide whether or not to create it. This is done to avoid any | ||
| * unnecessary plug-in loading. | ||
| */ | ||
| protected void checkHovers() | ||
| { | ||
| for (PHPTextHoverDescriptor descriptor : new ArrayList<PHPTextHoverDescriptor>(textHoverDescriptors)) | ||
| { | ||
| try | ||
| { | ||
| AbstractPHPTextHover hover = descriptor.createTextHover(); | ||
| if (hover != null) | ||
| { | ||
| // Make sure that the debug-hover is first. | ||
| if (DEBUG_HOVER_ID.equals(descriptor.getId())) | ||
| { | ||
| instantiatedTextHovers.add(0, hover); | ||
| } | ||
| else | ||
| { | ||
| instantiatedTextHovers.add(hover); | ||
| } | ||
| textHoverDescriptors.remove(descriptor); | ||
| } | ||
| } | ||
| catch (Exception e) | ||
| { | ||
| PHPEditorPlugin.logError(e); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /* | ||
| * (non-Javadoc) | ||
| * @see com.aptana.editor.common.hover.AbstractDocumentationHover#getHeader(java.lang.Object, | ||
| * org.eclipse.ui.IEditorPart, org.eclipse.jface.text.IRegion) | ||
| */ | ||
| @Override | ||
| public String getHeader(Object element, IEditorPart editorPart, IRegion hoverRegion) | ||
| { | ||
| if (bestHover instanceof AbstractDocumentationHover) | ||
| { | ||
| return ((AbstractDocumentationHover) bestHover).getHeader(element, editorPart, hoverRegion); | ||
| } | ||
| return null; | ||
| } | ||
|
|
||
| /* | ||
| * (non-Javadoc) | ||
| * @see com.aptana.editor.common.hover.AbstractDocumentationHover#getDocumentation(java.lang.Object, | ||
| * org.eclipse.ui.IEditorPart, org.eclipse.jface.text.IRegion) | ||
| */ | ||
| @Override | ||
| public String getDocumentation(Object element, IEditorPart editorPart, IRegion hoverRegion) | ||
| { | ||
| if (bestHover instanceof AbstractDocumentationHover) | ||
| { | ||
| return ((AbstractDocumentationHover) bestHover).getDocumentation(element, editorPart, hoverRegion); | ||
| } | ||
| return null; | ||
| } | ||
|
|
||
| /* | ||
| * (non-Javadoc) | ||
| * @see com.aptana.editor.common.hover.AbstractDocumentationHover#populateToolbarActions(org.eclipse.jface.action. | ||
| * ToolBarManager, com.aptana.editor.common.hover.CustomBrowserInformationControl) | ||
| */ | ||
| @Override | ||
| public void populateToolbarActions(ToolBarManager tbm, CustomBrowserInformationControl iControl) | ||
| { | ||
| if (bestHover instanceof AbstractDocumentationHover) | ||
| { | ||
| ((AbstractDocumentationHover) bestHover).populateToolbarActions(tbm, iControl); | ||
| } | ||
| } | ||
| } |
| @@ -0,0 +1,71 @@ | ||
| /** | ||
| * Aptana Studio | ||
| * Copyright (c) 2005-2012 by Appcelerator, Inc. All Rights Reserved. | ||
| * Licensed under the terms of the Eclipse Public License (EPL). | ||
| * Please see the license-epl.html included with this distribution for details. | ||
| * Any modifications to this file must keep this entire header intact. | ||
| */ | ||
| package com.aptana.editor.php.internal.ui.hover; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| import org.eclipse.core.runtime.IConfigurationElement; | ||
| import org.eclipse.core.runtime.IExtensionRegistry; | ||
| import org.eclipse.core.runtime.Platform; | ||
|
|
||
| import com.aptana.editor.php.PHPEditorPlugin; | ||
|
|
||
| /** | ||
| * PHP text hovers registry. | ||
| * | ||
| * @author Shalom Gibly <sgibly@aptana.com> | ||
| */ | ||
| public class PHPHoverRegistry | ||
| { | ||
| private static final String EXTENSION_POINT_NAME = "phpTextHovers"; //$NON-NLS-1$ | ||
| private static final String EXTENSION_NAME = "textHover"; //$NON-NLS-1$ | ||
|
|
||
| private static PHPHoverRegistry instance; | ||
|
|
||
| /** | ||
| * Returns an instance of the registry. | ||
| */ | ||
| public static PHPHoverRegistry getInstance() | ||
| { | ||
| if (instance == null) | ||
| { | ||
| instance = new PHPHoverRegistry(); | ||
| } | ||
| return instance; | ||
| } | ||
|
|
||
| private List<PHPTextHoverDescriptor> hovers; | ||
|
|
||
| /** | ||
| * Returns the registered PHP text hovers descriptors.<br> | ||
| * The descriptors can later be instantiated to create an instance of the text hover. | ||
| * | ||
| * @return A list of registered PHP text hover descriptors. | ||
| */ | ||
| @SuppressWarnings("unchecked") | ||
| public synchronized List<PHPTextHoverDescriptor> getTextHoversDescriptors() | ||
| { | ||
| if (hovers == null) | ||
| { | ||
| IExtensionRegistry registry = Platform.getExtensionRegistry(); | ||
| IConfigurationElement[] elements = registry.getConfigurationElementsFor(PHPEditorPlugin.PLUGIN_ID, | ||
| EXTENSION_POINT_NAME); | ||
| hovers = new ArrayList<PHPTextHoverDescriptor>(3); | ||
| for (IConfigurationElement element : elements) | ||
| { | ||
| if (element.getName().equals(EXTENSION_NAME)) | ||
| { | ||
| hovers.add(new PHPTextHoverDescriptor(element)); | ||
| } | ||
| } | ||
| } | ||
| return (List<PHPTextHoverDescriptor>) ((ArrayList<PHPTextHoverDescriptor>) hovers).clone(); | ||
| } | ||
|
|
||
| } |
| @@ -0,0 +1,75 @@ | ||
| /** | ||
| * Aptana Studio | ||
| * Copyright (c) 2005-2012 by Appcelerator, Inc. All Rights Reserved. | ||
| * Licensed under the terms of the Eclipse Public License (EPL). | ||
| * Please see the license-epl.html included with this distribution for details. | ||
| * Any modifications to this file must keep this entire header intact. | ||
| */ | ||
| package com.aptana.editor.php.internal.ui.hover; | ||
|
|
||
| import org.eclipse.core.runtime.CoreException; | ||
| import org.eclipse.core.runtime.IConfigurationElement; | ||
| import org.eclipse.core.runtime.Platform; | ||
| import org.osgi.framework.Bundle; | ||
|
|
||
| /** | ||
| * A descriptor for a PHP text hover. A caller can use this descriptor to instantiate a text hover instance. | ||
| * | ||
| * @author Shalom Gibly <sgibly@aptana.com> | ||
| */ | ||
| public class PHPTextHoverDescriptor | ||
| { | ||
|
|
||
| private static final String ATTR_ID = "id"; //$NON-NLS-1$ | ||
| private static final String ATTR_ACTIVATE_PLUGIN = "activatePlugin"; //$NON-NLS-1$ | ||
| private static final String ATTR_CLASS = "class"; //$NON-NLS-1$ | ||
| private IConfigurationElement element; | ||
| private String id; | ||
| private boolean canActivatePlugin; | ||
|
|
||
| /** | ||
| * @param element | ||
| */ | ||
| public PHPTextHoverDescriptor(IConfigurationElement element) | ||
| { | ||
| this.element = element; | ||
| this.id = element.getAttribute(ATTR_ID); | ||
| this.canActivatePlugin = Boolean.parseBoolean(element.getAttribute(ATTR_ACTIVATE_PLUGIN)); | ||
| } | ||
|
|
||
| /** | ||
| * Returns the descriptor's ID. | ||
| * | ||
| * @return The ID | ||
| */ | ||
| public String getId() | ||
| { | ||
| return this.id; | ||
| } | ||
|
|
||
| /** | ||
| * Returns true if this hover is allowed to activate the plugin that contributed it. | ||
| */ | ||
| public boolean canActivatePlugin() | ||
| { | ||
| return canActivatePlugin; | ||
| } | ||
|
|
||
| /** | ||
| * Instantiate a text hover. In case the hover is on a plugin that is not loaded yet, we look into the | ||
| * {@link #canActivatePlugin()} to determine if we can instantiate it anyway. | ||
| * | ||
| * @return An instance of AbstractPHPTextHover; Null, in case an un-loaded plugin is not allowed to be loaded. | ||
| * @throws CoreException | ||
| */ | ||
| public AbstractPHPTextHover createTextHover() throws CoreException | ||
| { | ||
| String contributor = element.getContributor().getName(); | ||
| boolean isPluginActivated = Platform.getBundle(contributor).getState() == Bundle.ACTIVE; | ||
| if (isPluginActivated || canActivatePlugin()) | ||
| { | ||
| return (AbstractPHPTextHover) element.createExecutableExtension(ATTR_CLASS); | ||
| } | ||
| return null; | ||
| } | ||
| } |