Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 31221 Details for
Bug 106199
[plan item] Improve task assistance in text fields
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
patch for org.eclipse.jface
org.eclipse.jface.taskassist.patch (text/plain), 72.25 KB, created by
Susan McCourt
on 2005-12-06 14:06:15 EST
(
hide
)
Description:
patch for org.eclipse.jface
Filename:
MIME Type:
Creator:
Susan McCourt
Created:
2005-12-06 14:06:15 EST
Size:
72.25 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.jface >Index: src/org/eclipse/jface/dialogs/taskassistance/FieldDecoration.java >=================================================================== >RCS file: src/org/eclipse/jface/dialogs/taskassistance/FieldDecoration.java >diff -N src/org/eclipse/jface/dialogs/taskassistance/FieldDecoration.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/dialogs/taskassistance/FieldDecoration.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,67 @@ >+/******************************************************************************* >+ * Copyright (c) 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.jface.dialogs.taskassistance; >+ >+import org.eclipse.swt.graphics.Image; >+ >+/** >+ * Simple data structure class for specifying a decoration for a field. >+ * >+ * <p> >+ * This API is considered experimental. It is still evolving during 3.2 and is >+ * subject to change. It is being released to obtain feedback from early >+ * adopters. >+ * >+ * @since 3.2 >+ */ >+public class FieldDecoration { >+ >+ private Image image; >+ >+ private String description; >+ >+ /** >+ * Create a decoration for a field with the specified image and description >+ * text. >+ * >+ * @param image >+ * the image shown in the decoration. >+ * @param description >+ * the description shown when the user hovers over the >+ * decoration. >+ */ >+ public FieldDecoration(Image image, String description) { >+ this.image = image; >+ this.description = description; >+ } >+ >+ /** >+ * Return the image shown in the decoration, or <code>null</code> if no >+ * image is specified. >+ * >+ * @return the image shown in the decoration. A return value of >+ * <code>null</code> signifies a blank decoration. >+ */ >+ public Image getImage() { >+ return image; >+ } >+ >+ /** >+ * Return the description for the decoration shown when the user hovers over >+ * the decoration. >+ * >+ * @return the String description of the decoration. A return value of >+ * <code>null</code> indicates that no description will be shown. >+ */ >+ public String getDescription() { >+ return description; >+ } >+} >Index: src/org/eclipse/jface/dialogs/taskassistance/ContentProposalPopup.java >=================================================================== >RCS file: src/org/eclipse/jface/dialogs/taskassistance/ContentProposalPopup.java >diff -N src/org/eclipse/jface/dialogs/taskassistance/ContentProposalPopup.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/dialogs/taskassistance/ContentProposalPopup.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,527 @@ >+/******************************************************************************* >+ * Copyright (c) 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.jface.dialogs.taskassistance; >+ >+import org.eclipse.core.runtime.Assert; >+import org.eclipse.jface.dialogs.Dialog; >+import org.eclipse.jface.dialogs.PopupDialog; >+import org.eclipse.jface.viewers.ILabelProvider; >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.events.SelectionEvent; >+import org.eclipse.swt.events.SelectionListener; >+import org.eclipse.swt.graphics.FontMetrics; >+import org.eclipse.swt.graphics.GC; >+import org.eclipse.swt.graphics.Image; >+import org.eclipse.swt.graphics.Point; >+import org.eclipse.swt.graphics.Rectangle; >+import org.eclipse.swt.layout.GridData; >+import org.eclipse.swt.widgets.Composite; >+import org.eclipse.swt.widgets.Control; >+import org.eclipse.swt.widgets.Event; >+import org.eclipse.swt.widgets.Listener; >+import org.eclipse.swt.widgets.Shell; >+import org.eclipse.swt.widgets.Table; >+import org.eclipse.swt.widgets.TableItem; >+import org.eclipse.swt.widgets.Text; >+ >+/** >+ * A lightweight popup used to show content proposals for a text field. If >+ * additional information exists for a proposal, then selecting that proposal >+ * will result in the information being displayed in a secondary popup. >+ * >+ * <p> >+ * This API is considered experimental. It is still evolving during 3.2 and is >+ * subject to change. It is being released to obtain feedback from early >+ * adopters. For now, there is limited API to control how the popup is sized or >+ * placed relative to the control, or whether it is resizable. The intention is >+ * that standard techniques will be implemented to "do the right thing" >+ * depending on the associated control's size/location and the content size, and >+ * API added if we discover there are additional choices to be made. >+ * >+ * @since 3.2 >+ */ >+public class ContentProposalPopup extends PopupDialog { >+ >+ /** >+ * Set to <code>true</code> to use a Table with SWT.VIRTUAL. This is a >+ * workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=98585#c40 >+ * The corresponding SWT bug is >+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=90321 >+ */ >+ private static final boolean USE_VIRTUAL = !"motif".equals(SWT.getPlatform()); //$NON-NLS-1$ >+ >+ /** >+ * The delay before showing a secondary popup. >+ */ >+ private static final int POPUP_DELAY = 500; >+ >+ /** >+ * The width hint for the popup and secondary popup. >+ */ >+ private static final int POPUP_CHARWIDTH = 20; >+ >+ /* >+ * The listener we will install on the target control. >+ */ >+ private final class TargetControlListener implements Listener { >+ // Key events from the control >+ public void handleEvent(Event e) { >+ if (!isValid()) >+ return; >+ >+ if (!(e.type == SWT.KeyDown || e.type == SWT.Traverse)) >+ return; >+ >+ // Traverse events will be ignored, but we will interpret their >+ // characters. >+ if (e.type == SWT.Traverse) { >+ e.detail = SWT.TRAVERSE_NONE; >+ e.doit = false; >+ } >+ >+ char key = e.character; >+ if (key == 0) { >+ int newSelection = proposalTable.getSelectionIndex(); >+ int visibleRows = (proposalTable.getSize().y / proposalTable >+ .getItemHeight()) - 1; >+ switch (e.keyCode) { >+ case SWT.ARROW_UP: >+ newSelection -= 1; >+ if (newSelection < 0) >+ newSelection = proposalTable.getItemCount() - 1; >+ break; >+ >+ case SWT.ARROW_DOWN: >+ newSelection += 1; >+ if (newSelection > proposalTable.getItemCount() - 1) >+ newSelection = 0; >+ break; >+ >+ case SWT.PAGE_DOWN: >+ newSelection += visibleRows; >+ if (newSelection >= proposalTable.getItemCount()) >+ newSelection = proposalTable.getItemCount() - 1; >+ break; >+ >+ case SWT.PAGE_UP: >+ newSelection -= visibleRows; >+ if (newSelection < 0) >+ newSelection = 0; >+ break; >+ >+ case SWT.HOME: >+ newSelection = 0; >+ break; >+ >+ case SWT.END: >+ newSelection = proposalTable.getItemCount() - 1; >+ break; >+ default: >+ if (e.keyCode != SWT.CAPS_LOCK && e.keyCode != SWT.MOD1 >+ && e.keyCode != SWT.MOD2 && e.keyCode != SWT.MOD3 >+ && e.keyCode != SWT.MOD4) >+ close(); >+ return; >+ } >+ >+ if (newSelection >= 0) >+ selectProposal(newSelection); >+ e.doit = false; >+ } >+ >+ // key != 0 >+ switch (key) { >+ case SWT.ESC: // Esc >+ e.doit = false; >+ close(); >+ break; >+ >+ case SWT.LF: >+ case SWT.CR: >+ e.doit = false; >+ Object p = getSelectedProposal(); >+ if (p != null) >+ adapter.proposalAccepted(getString(p)); >+ close(); >+ break; >+ >+ case SWT.TAB: >+ e.doit = false; >+ getShell().setFocus(); >+ return; >+ >+ default: >+ break; >+ } >+ } >+ } >+ >+ private class InfoPopupDialog extends PopupDialog { >+ >+ private static final String EMPTY = ""; //$NON-NLS-1$ >+ >+ private Text text; >+ >+ private String contents = EMPTY; >+ >+ InfoPopupDialog(Shell parent) { >+ super(parent, PopupDialog.HOVER_SHELLSTYLE, false, false, false, >+ false, null, null); >+ } >+ >+ /* >+ * Create a text control for showing the info about a proposal. >+ */ >+ protected Control createDialogArea(Composite parent) { >+ text = new Text(parent, SWT.MULTI | SWT.READ_ONLY | SWT.WRAP); >+ GridData gd = new GridData(GridData.BEGINNING | GridData.FILL_BOTH); >+ gd.horizontalIndent = PopupDialog.POPUP_HORIZONTALSPACING; >+ gd.verticalIndent = PopupDialog.POPUP_VERTICALSPACING; >+ text.setLayoutData(gd); >+ text.setText(contents); >+ return text; >+ } >+ >+ /* >+ * Adjust the bounds to appear next to our parent shell >+ */ >+ protected void adjustBounds() { >+ Rectangle parentBounds = getParentShell().getBounds(); >+ getShell().setBounds( >+ new Rectangle(parentBounds.x + parentBounds.width + PopupDialog.POPUP_HORIZONTALSPACING, >+ parentBounds.y + PopupDialog.POPUP_VERTICALSPACING, >+ parentBounds.width, parentBounds.height)); >+ >+ } >+ >+ void setContents(String newContents) { >+ if (newContents == null) >+ newContents = EMPTY; >+ this.contents = newContents; >+ if (text != null && !text.isDisposed()) { >+ text.setText(contents); >+ } >+ } >+ } >+ >+ /* >+ * The adapter on the target control. >+ */ >+ private ContentProposalAdapter adapter; >+ >+ /* >+ * The listener installed on the target control. >+ */ >+ private Listener controlListener; >+ >+ /* >+ * The control on which we are proposing content. >+ */ >+ private Control control; >+ >+ /* >+ * The table used to show the list of proposals. >+ */ >+ private Table proposalTable; >+ >+ /* >+ * The provider of proposals and proposal descriptions >+ */ >+ private IContentProposalProvider proposalProvider; >+ >+ /* >+ * The proposals to be shown (cached to avoid repeated requests). >+ */ >+ private Object[] proposals; >+ >+ /* >+ * A label provider >+ */ >+ private ILabelProvider labelProvider; >+ >+ /* >+ * Secondary popup used to show detailed information. >+ */ >+ private InfoPopupDialog infoPopup; >+ >+ /** >+ * Constructs a new instance of this popup, specifying the control for which >+ * this popup is showing content, and describing how the popup should be >+ * sized and placed. >+ * >+ * @param adapter >+ * the content proposal adapter that opened this dialog. >+ * @param control >+ * the control whose content is being proposed. >+ * @param proposalProvider >+ * the provider of content proposals >+ * @param infoText >+ * Text to be shown in a lower info area, or <code>null</code> >+ * if there is no info area. >+ * @param labelProvider >+ * the <code>ILabelProvider</code> used to obtain visual >+ * content for the proposals. Must never be <code>null</code>. >+ */ >+ public ContentProposalPopup(ContentProposalAdapter adapter, >+ Control control, IContentProposalProvider proposalProvider, >+ String infoText, ILabelProvider labelProvider) { >+ super(control.getShell(), PopupDialog.INFOPOPUPRESIZE_SHELLSTYLE, >+ false, false, false, false, null, infoText); >+ this.adapter = adapter; >+ this.control = control; >+ this.labelProvider = labelProvider; >+ this.proposalProvider = proposalProvider; >+ this.proposals = getProposals(adapter.getControlContent()); >+ } >+ >+ /** >+ * Creates the content area for the proposal popup. This creates a table and >+ * places it inside the composite. The table will contain a list of all the >+ * proposals. >+ * >+ * @param parent >+ * The parent composite to contain the dialog area; must not be >+ * <code>null</code>. >+ */ >+ protected final Control createDialogArea(final Composite parent) { >+ if (USE_VIRTUAL) { >+ proposalTable = new Table(parent, SWT.H_SCROLL | SWT.V_SCROLL >+ | SWT.VIRTUAL); >+ >+ Listener listener = new Listener() { >+ public void handleEvent(Event event) { >+ handleSetData(event); >+ } >+ }; >+ proposalTable.addListener(SWT.SetData, listener); >+ } else { >+ proposalTable = new Table(parent, SWT.H_SCROLL | SWT.V_SCROLL); >+ } >+ // set the proposals to force population of the table. >+ setProposals(proposals); >+ >+ proposalTable.setHeaderVisible(false); >+ proposalTable.addSelectionListener(new SelectionListener() { >+ >+ public void widgetSelected(SelectionEvent e) { >+ } >+ >+ public void widgetDefaultSelected(SelectionEvent e) { >+ adapter.proposalAccepted(getString(getSelectedProposal())); >+ } >+ }); >+ >+ GridData data = new GridData(GridData.FILL_BOTH); >+ GC gc = new GC(proposalTable); >+ gc.setFont(proposalTable.getFont()); >+ FontMetrics fontMetrics = gc.getFontMetrics(); >+ gc.dispose(); >+ data.widthHint = Dialog.convertWidthInCharsToPixels(fontMetrics, POPUP_CHARWIDTH); >+ proposalTable.setLayoutData(data); >+ return proposalTable; >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.eclipse.jface.dialogs.PopupDialog.adjustBounds() >+ */ >+ protected void adjustBounds() { >+ // Get our control's location in display coordinates. >+ Point location = control.getDisplay().map(control.getParent(), null, >+ control.getLocation()); >+ getShell().setLocation(location.x + 3, >+ location.y + control.getSize().y + 3); >+ } >+ >+ /** >+ * Set the content of the table to show the current proposals. >+ * >+ * @param event >+ */ >+ private void handleSetData(Event event) { >+ TableItem item = (TableItem) event.item; >+ int index = proposalTable.indexOf(item); >+ >+ if (0 <= index && index < proposals.length) { >+ Object current = proposals[index]; >+ item.setText(getString(current)); >+ item.setImage(getImage(current)); >+ item.setData(current); >+ } else { >+ // this should not happen, but does on win32 >+ } >+ } >+ >+ /** >+ * Initializes the proposal popup with these given proposals. >+ * >+ * @param proposals >+ * the proposals >+ */ >+ private void setProposals(Object[] proposals) { >+ if (proposals == null || proposals.length == 0) { >+ proposals = getEmptyProposalArray(); >+ } >+ >+ if (isValid()) { >+ final int newSize = proposals.length; >+ if (USE_VIRTUAL) { >+ proposalTable.setItemCount(newSize); >+ proposalTable.clearAll(); >+ } else { >+ proposalTable.setRedraw(false); >+ proposalTable.setItemCount(newSize); >+ TableItem[] items = proposalTable.getItems(); >+ for (int i = 0; i < items.length; i++) { >+ TableItem item = items[i]; >+ Object proposal = proposals[i]; >+ item.setText(getString(proposal)); >+ item.setImage(getImage(proposal)); >+ item.setData(proposal); >+ } >+ proposalTable.setRedraw(true); >+ } >+ proposalTable.setSelection(0); >+ proposalTable.showSelection(); >+ } >+ } >+ >+ private String getString(Object proposal) { >+ if (proposal == null) >+ return "Invalid proposal"; //$NON-NLS-1$ >+ if (labelProvider == null) >+ return proposal.toString(); >+ return labelProvider.getText(proposal); >+ } >+ >+ private Image getImage(Object proposal) { >+ if (proposal == null || labelProvider == null) >+ return null; >+ return labelProvider.getImage(proposal); >+ } >+ >+ private Object[] getEmptyProposalArray() { >+ return new Object[0]; >+ } >+ >+ private void addControlListener() { >+ controlListener = new TargetControlListener(); >+ control.addListener(SWT.KeyDown, controlListener); >+ control.addListener(SWT.Traverse, controlListener); >+ } >+ >+ private void removeControlListener() { >+ control.removeListener(SWT.KeyDown, controlListener); >+ control.removeListener(SWT.Traverse, controlListener); >+ } >+ >+ private boolean isValid() { >+ return proposalTable != null && !proposalTable.isDisposed(); >+ } >+ >+ /** >+ * Return the current selected proposal. >+ */ >+ private Object getSelectedProposal() { >+ if (isValid()) { >+ int i = proposalTable.getSelectionIndex(); >+ if (proposals == null || i < 0 || i >= proposals.length) >+ return null; >+ return proposals[i]; >+ } >+ return null; >+ } >+ >+ /** >+ * Select the proposal at the given index. >+ */ >+ private void selectProposal(int index) { >+ Assert.isTrue(index >= 0, "Proposal index should never be negative"); //$NON-NLS-1$ >+ if (!isValid() || proposals == null || index >= proposals.length) >+ return; >+ proposalTable.setSelection(index); >+ proposalTable.showSelection(); >+ >+ String description = getProposalDescription(proposals[index]); >+ showProposalDescription(description); >+ } >+ >+ /** >+ * Opens this window, creating it first if it has not yet been created. >+ * <p> >+ * This method is extended in order to add the control listener when the popup >+ * is opened and to invoke the secondary popup if applicable. >+ * >+ * @return the return code >+ * >+ * @see org.eclipse.jface.window.Window#open() >+ */ >+ public int open() { >+ addControlListener(); >+ int value = super.open(); >+ showProposalDescription(getProposalDescription(getSelectedProposal())); >+ return value; >+ } >+ >+ /** >+ * Closes this window, disposes its shell, and removes this window from its >+ * window manager (if it has one). >+ * <p> >+ * This method is extended to remove the control listener. >+ * </p> >+ * >+ * @return <code>true</code> if the window is (or was already) closed, and >+ * <code>false</code> if it is still open >+ */ >+ public boolean close() { >+ removeControlListener(); >+ return super.close(); >+ } >+ >+ private Object[] getProposals(String contents) { >+ if (proposalProvider == null) >+ return null; >+ if (proposalProvider instanceof IFilteringContentProposalProvider) >+ return ((IFilteringContentProposalProvider)proposalProvider).getProposals(contents); >+ return proposalProvider.getProposals(); >+ } >+ >+ private String getProposalDescription(Object proposal) { >+ if (proposalProvider == null) >+ return null; >+ return proposalProvider.getProposalDescription(proposal); >+ } >+ >+ private void showProposalDescription(String description) { >+ if (infoPopup == null && description != null) { >+ infoPopup = new InfoPopupDialog(getShell()); >+ infoPopup.setContents(description); >+ Runnable runnable = new Runnable() { >+ public void run() { >+ try { >+ Thread.sleep(POPUP_DELAY); >+ } catch (InterruptedException e) { >+ } >+ getShell().getDisplay().syncExec(new Runnable() { >+ public void run() { >+ infoPopup.open(); >+ } >+ }); >+ } >+ }; >+ Thread t = new Thread(runnable); >+ t.start(); >+ } else if (infoPopup != null) { >+ infoPopup.setContents(description); >+ } >+ } >+} >Index: src/org/eclipse/jface/dialogs/taskassistance/IContentProposalListener.java >=================================================================== >RCS file: src/org/eclipse/jface/dialogs/taskassistance/IContentProposalListener.java >diff -N src/org/eclipse/jface/dialogs/taskassistance/IContentProposalListener.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/dialogs/taskassistance/IContentProposalListener.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,28 @@ >+/******************************************************************************* >+ * Copyright (c) 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.jface.dialogs.taskassistance; >+ >+/** >+ * <p> >+ * This interface is used to listen to notifications from a >+ * ContentProposalAdapter. >+ * >+ * @since 3.2 >+ */ >+public interface IContentProposalListener { >+ /** >+ * A content proposal has been accepted. >+ * >+ * @param proposal >+ * the proposed content string. >+ */ >+ public void proposalAccepted(String proposal); >+} >Index: src/org/eclipse/jface/dialogs/taskassistance/IControlCreator.java >=================================================================== >RCS file: src/org/eclipse/jface/dialogs/taskassistance/IControlCreator.java >diff -N src/org/eclipse/jface/dialogs/taskassistance/IControlCreator.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/dialogs/taskassistance/IControlCreator.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,41 @@ >+/******************************************************************************* >+ * Copyright (c) 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.jface.dialogs.taskassistance; >+ >+import org.eclipse.swt.widgets.Composite; >+import org.eclipse.swt.widgets.Control; >+ >+/** >+ * This interface is used to create a control with a specific parent and style >+ * bits. It is used by DecoratedFields to create a specific kind of control. >+ * Clients are expected to implement this interface in order to create a >+ * particular kind of control for decoration. >+ * >+ * <p> >+ * This API is considered experimental. It is still evolving during 3.2 and is >+ * subject to change. It is being released to obtain feedback from early >+ * adopters. >+ * >+ * @since 3.2 >+ */ >+public interface IControlCreator { >+ /** >+ * Create a control with the specified parent and style bits. >+ * >+ * @param parent >+ * the parent of the control >+ * @param style >+ * the style of the control >+ * >+ * @return the Control that was created. >+ */ >+ public Control createControl(Composite parent, int style); >+} >Index: src/org/eclipse/jface/dialogs/taskassistance/ContentProposalAdapter.java >=================================================================== >RCS file: src/org/eclipse/jface/dialogs/taskassistance/ContentProposalAdapter.java >diff -N src/org/eclipse/jface/dialogs/taskassistance/ContentProposalAdapter.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/dialogs/taskassistance/ContentProposalAdapter.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,345 @@ >+/******************************************************************************* >+ * Copyright (c) 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.jface.dialogs.taskassistance; >+ >+import org.eclipse.core.runtime.ListenerList; >+import org.eclipse.jface.bindings.keys.KeyStroke; >+import org.eclipse.jface.util.Assert; >+import org.eclipse.jface.viewers.ILabelProvider; >+import org.eclipse.jface.viewers.LabelProvider; >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.widgets.Control; >+import org.eclipse.swt.widgets.Event; >+import org.eclipse.swt.widgets.Listener; >+ >+/** >+ * A content proposal adapter can be used to attach content proposal behavior to >+ * a control. This behavior includes obtaining proposals, opening a popup >+ * dialog, managing the content of the control relative to the selections in the >+ * popup, and optionally opening up a secondary popup to further describe >+ * proposals. >+ * >+ * <p> >+ * This API is considered experimental. It is still evolving during 3.2 and is >+ * subject to change. It is being released to obtain feedback from early >+ * adopters. >+ * >+ * @since 3.2 >+ */ >+public class ContentProposalAdapter { >+ >+ /** >+ * Flag that controls the printing of debug info. >+ */ >+ public static final boolean DEBUG = false; >+ >+ /** >+ * Indicates that a chosen proposal should be inserted into the field. >+ */ >+ public static final int PROPOSAL_INSERT = 1; >+ >+ /** >+ * Indicates that a chosen proposal should replace the current contents of >+ * the field. >+ */ >+ public static final int PROPOSAL_REPLACE = 2; >+ >+ /** >+ * Indicates that a chosen proposal should be ignored. This is typically >+ * used when the client code implements specialized behavior that occurs >+ * when a proposal is chosen. In this case, clients typically register an >+ * IContentProposalListener so that they are notified when a proposal is >+ * chosen. >+ */ >+ public static final int PROPOSAL_IGNORE = 3; >+ >+ /* >+ * A string containing the characters that auto-trigger content assist. >+ */ >+ >+ private IContentProposalProvider proposalProvider; >+ >+ private ILabelProvider labelProvider; >+ >+ private Control control; >+ >+ private IControlContentAdapter controlContentAdapter; >+ >+ private ContentProposalPopup popup; >+ >+ private KeyStroke triggerKeyStroke; >+ >+ private int acceptance; >+ >+ private boolean propagateKeyStroke; >+ >+ private Listener controlListener; >+ >+ private ListenerList proposalListeners = new ListenerList(); >+ >+ /** >+ * Construct a content proposal adapter that can assist the user with >+ * choosing content for the field. >+ * >+ * @param control >+ * the control for which the adapter is providing content assist. >+ * @param controlContentAdapter >+ * the <code>IControlContentAdapter</code> used to obtain and >+ * update the control's contents as proposals are accepted. >+ * @param proposalProvider >+ * the <code>IContentProposalProvider</code> used to obtain >+ * content proposals for this control, or <code>null</code> if >+ * no content proposal is available. >+ * @param labelProvider >+ * the label provider which provides text and image information >+ * for content proposals. A <code>null</code> value indicates >+ * that a default label provider is sufficient for any content >+ * proposals that may occur. >+ * @param keyStroke >+ * the keystroke that will invoke the content proposal popup. >+ * @param propagateKeyStroke >+ * a boolean that indicates whether the triggering keystroke >+ * should be propagated to the adapted control. >+ * @param acceptance >+ * a constant indicating how an accepted proposal should affect >+ * the control's content. Should be one of >+ * <code>PROPOSAL_INSERT</code>, <code>PROPOSAL_REPLACE</code>, >+ * or <code>PROPOSAL_IGNORE</code> >+ * >+ */ >+ public ContentProposalAdapter(Control control, >+ IControlContentAdapter controlContentAdapter, >+ IContentProposalProvider proposalProvider, >+ ILabelProvider labelProvider, KeyStroke keyStroke, >+ boolean propagateKeyStroke, int acceptance) { >+ super(); >+ this.control = control; >+ this.controlContentAdapter = controlContentAdapter; >+ this.proposalProvider = proposalProvider; >+ this.labelProvider = labelProvider; >+ this.triggerKeyStroke = keyStroke; >+ this.propagateKeyStroke = propagateKeyStroke; >+ this.acceptance = acceptance; >+ addControlListener(control); >+ } >+ >+ /** >+ * Get the control on which the content proposal adapter is installed. >+ * >+ * @return the control on which the proposal adapter is installed. >+ */ >+ public Control getControl() { >+ return control; >+ } >+ >+ /** >+ * Get the label provider that is used to show proposals. A default label >+ * provider will be used if one has not been set. >+ * >+ * @return the <code>ILabelProvider</code> used to show proposals >+ */ >+ public ILabelProvider getLabelProvider() { >+ if (labelProvider == null) { >+ labelProvider = new LabelProvider(); >+ } >+ return labelProvider; >+ } >+ >+ /** >+ * Set the label provider that is used to show proposals. >+ * >+ * @param labelProvider >+ * the <code>ILabelProvider</code> used to show proposals. >+ */ >+ public void setLabelProvider(ILabelProvider labelProvider) { >+ this.labelProvider = labelProvider; >+ } >+ >+ /** >+ * Get the proposal provider that provides content proposals given the >+ * current content of the field. A value of <code>null</code> indicates >+ * that there are no content proposals available for the field. >+ * >+ * @return the <code>IContentProposalProvider</code> used to show >+ * proposals. May be <code>null</code>. >+ */ >+ public IContentProposalProvider getContentProposalProvider() { >+ return proposalProvider; >+ } >+ >+ /** >+ * Set the content proposal provider that is used to show proposals. >+ * >+ * @param proposalProvider >+ * the <code>IContentProposalProvider</code> used to show >+ * proposals >+ */ >+ public void setContentProposalProvider( >+ IContentProposalProvider proposalProvider) { >+ this.proposalProvider = proposalProvider; >+ } >+ >+ /** >+ * Add the specified listener to the list of content proposal listeners that >+ * are notified when content proposals are chosen. >+ * </p> >+ * >+ * @param listener >+ * the IContentProposalListener to be added as a listener. Must >+ * not be <code>null</code>. If an attempt is made to register >+ * an instance which is already registered with this instance, >+ * this method has no effect. >+ * >+ * @see org.eclipse.jface.dialogs.taskassistance.IContentProposalListener >+ */ >+ public void addContentProposalListener(IContentProposalListener listener) { >+ proposalListeners.add(listener); >+ } >+ >+ private void addControlListener(Control control) { >+ if (DEBUG) >+ System.out >+ .println("ContentProposalListener#installControlListener()"); //$NON-NLS-1$ >+ >+ if (controlListener != null) >+ return; >+ controlListener = new Listener() { >+ public void handleEvent(Event e) { >+ switch (e.type) { >+ case SWT.KeyDown: >+ if (DEBUG) >+ dump("keyDown OK", e); //$NON-NLS-1$ >+ if (triggerKeyStroke != null) { >+ // Either there are no modifiers for the trigger and we >+ // check the character field... >+ if ((triggerKeyStroke.getModifierKeys() == KeyStroke.NO_KEY && triggerKeyStroke >+ .getNaturalKey() == e.character) >+ || >+ // ...or there are modifiers, in which case the >+ // keycode and state must match >+ (triggerKeyStroke.getNaturalKey() == e.keyCode && ((triggerKeyStroke >+ .getModifierKeys() & e.stateMask) == triggerKeyStroke >+ .getModifierKeys()))) { >+ e.doit = propagateKeyStroke; >+ openProposalPopup(); >+ >+ } >+ } >+ break; >+ >+ default: >+ Assert.isTrue(false); >+ } >+ } >+ >+ /** >+ * Dump the given events to "standard" output. >+ * >+ * @param who >+ * who dump's >+ * @param e >+ * the event >+ */ >+ private void dump(String who, Event e) { >+ StringBuffer sb = new StringBuffer( >+ "--- [ContentProposalAdapter]\n"); //$NON-NLS-1$ >+ sb.append(who); >+ sb.append(" - e: keyCode=" + e.keyCode + hex(e.keyCode)); //$NON-NLS-1$ >+ sb.append("; character=" + e.character + hex(e.character)); //$NON-NLS-1$ >+ sb.append("; stateMask=" + e.stateMask + hex(e.stateMask)); //$NON-NLS-1$ >+ sb.append("; doit=" + e.doit); //$NON-NLS-1$ >+ sb.append("; detail=" + e.detail + hex(e.detail)); //$NON-NLS-1$ >+ sb.append("; widget=" + e.widget); //$NON-NLS-1$ >+ System.out.println(sb); >+ } >+ >+ private String hex(int i) { >+ return "[0x" + Integer.toHexString(i) + ']'; //$NON-NLS-1$ >+ } >+ }; >+ control.addListener(SWT.KeyDown, controlListener); >+ >+ if (DEBUG) >+ System.out >+ .println("ContentProposalAdapter#installControlListener() - installed"); //$NON-NLS-1$ >+ } >+ >+ private void openProposalPopup() { >+ if (popup == null) { >+ popup = new ContentProposalPopup(this, control, proposalProvider, >+ null, labelProvider); >+ } >+ popup.open(); >+ } >+ >+ /** >+ * A content proposal has been accepted. Update the control contents >+ * accordingly and notify any listeners. >+ * >+ * @param text >+ * the text that was accepted as the proposal. >+ */ >+ public void proposalAccepted(String text) { >+ switch (acceptance) { >+ case (PROPOSAL_REPLACE): >+ setControlContent(text); >+ break; >+ case (PROPOSAL_INSERT): >+ insertControlContent(text); >+ break; >+ default: >+ // do nothing. Typically a listener is installed to handle this in >+ // a custom way. >+ break; >+ } >+ >+ // In all cases, notify listeners of an accepted proposal. >+ final Object[] listenerArray = proposalListeners.getListeners(); >+ for (int i = 0; i < listenerArray.length; i++) >+ ((IContentProposalListener) listenerArray[i]) >+ .proposalAccepted(text); >+ } >+ >+ /** >+ * Return the text content of the control. >+ * >+ * @return the String contents of the control. Never <code>null</code>. >+ */ >+ public String getControlContent() { >+ if (isValid()) >+ return controlContentAdapter.getControlContents(control); >+ return ""; //$NON-NLS-1$ >+ } >+ >+ /* >+ * Set the text content of the control >+ */ >+ private void setControlContent(String text) { >+ if (isValid()) >+ controlContentAdapter.setControlContents(control, text); >+ } >+ >+ /* >+ * Insert the specified text into the control content. >+ */ >+ private void insertControlContent(String text) { >+ if (isValid()) >+ controlContentAdapter.insertControlContents(control, text); >+ } >+ >+ /* >+ * Check that the control and content adapter are valid. >+ */ >+ private boolean isValid() { >+ return control != null && !control.isDisposed() >+ && controlContentAdapter != null; >+ } >+} >Index: src/org/eclipse/jface/dialogs/taskassistance/IControlContentAdapter.java >=================================================================== >RCS file: src/org/eclipse/jface/dialogs/taskassistance/IControlContentAdapter.java >diff -N src/org/eclipse/jface/dialogs/taskassistance/IControlContentAdapter.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/dialogs/taskassistance/IControlContentAdapter.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,59 @@ >+/******************************************************************************* >+ * Copyright (c) 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.jface.dialogs.taskassistance; >+ >+import org.eclipse.swt.widgets.Control; >+ >+/** >+ * This interface is used to set and retrieve text content from an arbitrary >+ * control. Clients are expected to implement this interface when defining a >+ * ContentProposalAdapter, in order to specify how to retrieve and set the >+ * contents of the control being adapted. >+ * >+ * <p> >+ * This API is considered experimental. It is still evolving during 3.2 and is >+ * subject to change. It is being released to obtain feedback from early >+ * adopters. >+ * >+ * @since 3.2 >+ */ >+public interface IControlContentAdapter { >+ /** >+ * Set the contents of the specified control to the specified text. Must not >+ * be <code>null</code>. >+ * >+ * @param control >+ * the control whose contents are to be set (replaced). >+ * @param contents >+ * the String specifying the new control content. >+ */ >+ public void setControlContents(Control control, String contents); >+ >+ /** >+ * Insert the specified contents into the control's current contents. Must >+ * not be <code>null</code>. >+ * >+ * @param control >+ * the control whose contents are to be altered. >+ * @param contents >+ * the String to be inserted into the control contents. >+ */ >+ public void insertControlContents(Control control, String contents); >+ >+ /** >+ * Get the text contents of the control. >+ * >+ * @param control >+ * the control whose contents are to be retrieved. >+ * @return the String contents of the control. >+ */ >+ public String getControlContents(Control control); >+} >Index: src/org/eclipse/jface/dialogs/taskassistance/SimpleContentProposalProvider.java >=================================================================== >RCS file: src/org/eclipse/jface/dialogs/taskassistance/SimpleContentProposalProvider.java >diff -N src/org/eclipse/jface/dialogs/taskassistance/SimpleContentProposalProvider.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/dialogs/taskassistance/SimpleContentProposalProvider.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,75 @@ >+/******************************************************************************* >+ * Copyright (c) 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.jface.dialogs.taskassistance; >+ >+/** >+ * The SimpleContentProposalProvider is a class designed to return a static list >+ * of items when queried for content proposals. >+ * <p> >+ * This API is considered experimental. It is still evolving during 3.2 and is >+ * subject to change. It is being released to obtain feedback from early >+ * adopters. >+ * >+ * @since 3.2 >+ * >+ */ >+public class SimpleContentProposalProvider implements IContentProposalProvider { >+ >+ // The proposals to display >+ private Object[] proposals; >+ >+ /** >+ * Construct a SimpleContentProposalProvider whose content proposals always >+ * consist of the specified array of Objects. >+ * >+ * @param proposals >+ * the array of Objects to be returned whenever proposals are >+ * requested. >+ */ >+ public SimpleContentProposalProvider(Object[] proposals) { >+ super(); >+ this.proposals = proposals; >+ } >+ >+ /** >+ * Return an array of Objects representing the valid content proposals for a >+ * field. >+ * >+ * @return the array of Objects that represent valid proposals for the field >+ * given its current content. >+ */ >+ public Object[] getProposals() { >+ return this.proposals; >+ } >+ >+ /** >+ * Set the proposals to be returned by the receiver whenever content >+ * proposals are requested. >+ * >+ * @param items >+ * Object[] >+ */ >+ public void setProposals(Object[] items) { >+ this.proposals = items; >+ } >+ >+ /** >+ * Return a String that describes the given proposal in more detail. >+ * >+ * @param proposal >+ * the Object representing a valid proposal >+ * @return return <code>null</code> to indicate that there is no >+ * description available. >+ */ >+ public String getProposalDescription(Object proposal) { >+ return null; >+ } >+} >Index: src/org/eclipse/jface/dialogs/taskassistance/package.html >=================================================================== >RCS file: src/org/eclipse/jface/dialogs/taskassistance/package.html >diff -N src/org/eclipse/jface/dialogs/taskassistance/package.html >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/dialogs/taskassistance/package.html 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,31 @@ >+<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> >+<html> >+<head> >+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> >+ <meta name="Author" content="IBM"> >+ <meta name="GENERATOR" content="Mozilla/4.5 [en] (Win98; I) [Netscape]"> >+ <title>Package-level Javadoc</title> >+</head> >+<body> >+Provides support for classes that help communicate proper content for dialogs and wizards. >+<h2> >+Package Specification</h2> >+<p> >+This package provides several classes that help users complete the content in a dialog >+or wizard. <tt>DecoratedField</tt> can be used to decorate controls with images that >+communicate information about the control's content. Decorations can be >+used to show additional information about a field, such as its status, or a cue >+that shows availability of content proposals. Decorated fields handle the creation >+of the field's control, since a specialized layout is used to manage the decoration. >+Otherwise, clients are expected to interact directly with the control. Decorations can >+optionally show descriptive text when the user hovers over them. >+</p> >+<p> >+A <tt>ContentProposalAdapter</tt> can be attached to a control to provide content >+proposals. These proposals are typically shown in a popup dialog as the user types information >+into a field, or when a special assist key is invoked. The <tt>ContentProposalAdapter</tt> >+manages the creation, hiding, and showing of the proposal popup. >+</p> >+<p>Note: None of the classes in this package maintain global state. >+</body> >+</html> >Index: src/org/eclipse/jface/dialogs/taskassistance/TextControlCreator.java >=================================================================== >RCS file: src/org/eclipse/jface/dialogs/taskassistance/TextControlCreator.java >diff -N src/org/eclipse/jface/dialogs/taskassistance/TextControlCreator.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/dialogs/taskassistance/TextControlCreator.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,33 @@ >+/******************************************************************************* >+ * Copyright (c) 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.jface.dialogs.taskassistance; >+ >+import org.eclipse.swt.widgets.Composite; >+import org.eclipse.swt.widgets.Control; >+import org.eclipse.swt.widgets.Text; >+ >+/** >+ * A Text control creator. Convenience class to create text controls to >+ * be supplied to a decorated field. >+ * >+ * <p> >+ * This API is considered experimental. It is still evolving during 3.2 and is >+ * subject to change. It is being released to obtain feedback from early >+ * adopters. >+ * >+ * @since 3.2 >+ */ >+public class TextControlCreator implements IControlCreator { >+ >+ public Control createControl(Composite parent, int style) { >+ return new Text(parent, style); >+ } >+} >Index: src/org/eclipse/jface/dialogs/taskassistance/IFilteringContentProposalProvider.java >=================================================================== >RCS file: src/org/eclipse/jface/dialogs/taskassistance/IFilteringContentProposalProvider.java >diff -N src/org/eclipse/jface/dialogs/taskassistance/IFilteringContentProposalProvider.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/dialogs/taskassistance/IFilteringContentProposalProvider.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,39 @@ >+/******************************************************************************* >+ * Copyright (c) 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.jface.dialogs.taskassistance; >+ >+/** >+ * An IFilteringProposalProvider provides a list of objects that are appropriate >+ * for a textual dialog field, given the field's current content. >+ * >+ * <p> >+ * This API is considered experimental. It is still evolving during 3.2 and is >+ * subject to change. It is being released to obtain feedback from early >+ * adopters. >+ * >+ * @since 3.2 >+ */ >+public interface IFilteringContentProposalProvider extends IContentProposalProvider { >+ >+ /** >+ * Return an array of Objects representing the valid content proposals for a >+ * field when it contains the given text content. >+ * >+ * @param content >+ * the String representing the current value of the field for >+ * which proposals are requested. >+ * @return the Objects that represent valid proposals for the field given >+ * its current content. The proposal may be a String, or an Object >+ * that will be mapped to a text value using an associated >+ * <code>org.eclipse.jface.viewers.ILabelProvider</code>. >+ */ >+ Object[] getProposals(String content); >+} >Index: src/org/eclipse/jface/dialogs/taskassistance/DecoratedField.java >=================================================================== >RCS file: src/org/eclipse/jface/dialogs/taskassistance/DecoratedField.java >diff -N src/org/eclipse/jface/dialogs/taskassistance/DecoratedField.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/dialogs/taskassistance/DecoratedField.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,655 @@ >+/******************************************************************************* >+ * Copyright (c) 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.jface.dialogs.taskassistance; >+ >+import org.eclipse.core.runtime.Assert; >+import org.eclipse.jface.dialogs.Dialog; >+import org.eclipse.jface.dialogs.IDialogConstants; >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.events.DisposeEvent; >+import org.eclipse.swt.events.DisposeListener; >+import org.eclipse.swt.events.FocusEvent; >+import org.eclipse.swt.events.FocusListener; >+import org.eclipse.swt.events.MouseAdapter; >+import org.eclipse.swt.events.MouseEvent; >+import org.eclipse.swt.events.MouseTrackListener; >+import org.eclipse.swt.events.PaintEvent; >+import org.eclipse.swt.events.PaintListener; >+import org.eclipse.swt.graphics.FontMetrics; >+import org.eclipse.swt.graphics.GC; >+import org.eclipse.swt.graphics.Point; >+import org.eclipse.swt.graphics.Region; >+import org.eclipse.swt.layout.FormAttachment; >+import org.eclipse.swt.layout.FormData; >+import org.eclipse.swt.layout.FormLayout; >+import org.eclipse.swt.layout.GridData; >+import org.eclipse.swt.widgets.Composite; >+import org.eclipse.swt.widgets.Control; >+import org.eclipse.swt.widgets.Display; >+import org.eclipse.swt.widgets.Label; >+import org.eclipse.swt.widgets.Shell; >+ >+/** >+ * A decorated field manages image decorations around a control. It allows >+ * clients to specify an image decoration and a position for the decoration >+ * relative to the field. Decorations may be assigned descriptions, which are >+ * shown when the user hovers over the decoration. Clients can decorate any kind >+ * of control by supplying an <code>IControlCreator</code> to create the >+ * control that is decorated. >+ * >+ * <p> >+ * This API is considered experimental. It is still evolving during 3.2 and is >+ * subject to change. It is being released to obtain feedback from early >+ * adopters. >+ * >+ * @since 3.2 >+ */ >+public class DecoratedField { >+ >+ /** >+ * Number of pixels to reserve for decorations. >+ */ >+ private static int RESERVED_WIDTH = 8; >+ >+ /** >+ * Cached platform flags for dealing with platform-specific issues. >+ */ >+ private static boolean CARBON = "carbon".equals(SWT.getPlatform()); //$NON-NLS-1$ >+ >+ /** >+ * Constants describing the array indices used to hold the decorations in >+ * array slots. >+ */ >+ >+ private static final int LEFT_TOP = 0; >+ >+ private static final int LEFT_BOTTOM = 1; >+ >+ private static final int RIGHT_TOP = 2; >+ >+ private static final int RIGHT_BOTTOM = 3; >+ >+ private static final int DECORATION_SLOTS = 4; >+ >+ /** >+ * Set the width (in pixels) that should always be reserved for field >+ * decorations, regardless of the actual width of any supplied decorations. >+ * Field alignment within dialogs will look best when all decorations >+ * supplied conform to the reserved width. However, the field decoration >+ * area for a particular field will be expanded if decorations larger than >+ * the reserved width are supplied. >+ * >+ * @param decorationWidth >+ */ >+ public static void setReservedDecorationWidth(int decorationWidth) { >+ RESERVED_WIDTH = decorationWidth; >+ } >+ >+ /** >+ * Simple data structure class for specifying the internals for a field >+ * decoration. This class contains data specific to the implementation of >+ * field decorations as labels attached to the field. Clients should use >+ * <code>FieldDecoration</code> for specifying a decoration. >+ */ >+ private class FieldDecorationData { >+ >+ /* Package */FieldDecoration decoration; >+ >+ /* Package */Label label; >+ >+ /* Package */FormData data; >+ >+ /* Package */boolean showOnFocus; >+ >+ /* Package */boolean visible = true; >+ >+ /** >+ * Create a decoration data representing the specified decoration, using >+ * the specified label and form data for its representation. >+ * >+ * @param decoration >+ * the decoration whose data is kept. >+ * @param label >+ * the label used to represent the decoration. >+ * @param formData >+ * the form data used to attach the decoration to its field. >+ * @param showOnFocus >+ * a boolean specifying whether the decoration should only be >+ * shown when the field has focus. >+ */ >+ FieldDecorationData(FieldDecoration decoration, Label label, >+ FormData formData, boolean showOnFocus) { >+ this.decoration = decoration; >+ this.label = label; >+ this.data = formData; >+ this.showOnFocus = showOnFocus; >+ } >+ } >+ >+ /** >+ * Decorations keyed by position. >+ */ >+ private FieldDecorationData[] decDatas = new FieldDecorationData[DECORATION_SLOTS]; >+ >+ /** >+ * The associated control >+ */ >+ private Control control; >+ >+ /** >+ * The composite with form layout used to manage decorations. >+ */ >+ private Composite form; >+ >+ /** >+ * The hover used for showing description text >+ */ >+ private Hover hover; >+ >+ /** >+ * The hover used to show a decoration image's description. >+ */ >+ class Hover { >+ /** >+ * Offset of info hover arrow from the left or right side. >+ */ >+ private int a_OFFSET = 10; >+ >+ /** >+ * Width of info hover arrow. >+ */ >+ private int a_WIDTH = 8; >+ >+ /** >+ * Height of info hover arrow. >+ */ >+ private int a_HEIGHT = 10; >+ >+ /** >+ * Margin around info hover text. >+ */ >+ private int h_MARGIN = 2; >+ >+ /** >+ * This info hover's shell. >+ */ >+ Shell hoverShell; >+ >+ /** >+ * The info hover text. >+ */ >+ String text = ""; //$NON-NLS-1$ >+ >+ Hover(Shell parent) { >+ final Display display = parent.getDisplay(); >+ hoverShell = new Shell(parent, SWT.NO_TRIM | SWT.ON_TOP >+ | SWT.NO_FOCUS); >+ hoverShell.setBackground(display >+ .getSystemColor(SWT.COLOR_INFO_BACKGROUND)); >+ hoverShell.setForeground(display >+ .getSystemColor(SWT.COLOR_INFO_FOREGROUND)); >+ hoverShell.addPaintListener(new PaintListener() { >+ public void paintControl(PaintEvent pe) { >+ pe.gc.drawString(text, h_MARGIN, h_MARGIN); >+ if (!CARBON) >+ pe.gc.drawPolygon(getPolygon(true)); >+ } >+ }); >+ hoverShell.addMouseListener(new MouseAdapter() { >+ public void mouseDown(MouseEvent e) { >+ hideHover(); >+ } >+ }); >+ } >+ >+ int[] getPolygon(boolean border) { >+ Point e = getExtent(); >+ if (border) >+ return new int[] { 0, 0, e.x - 1, 0, e.x - 1, e.y - 1, >+ a_OFFSET + a_WIDTH, e.y - 1, a_OFFSET + a_WIDTH / 2, >+ e.y + a_HEIGHT - 1, a_OFFSET, e.y - 1, 0, e.y - 1, 0, 0 }; >+ return new int[] { 0, 0, e.x, 0, e.x, e.y, a_OFFSET + a_WIDTH, e.y, >+ a_OFFSET + a_WIDTH / 2, e.y + a_HEIGHT, a_OFFSET, e.y, 0, >+ e.y, 0, 0 }; >+ } >+ >+ void dispose() { >+ if (!hoverShell.isDisposed()) >+ hoverShell.dispose(); >+ } >+ >+ void setVisible(boolean visible) { >+ if (visible) { >+ if (!hoverShell.isVisible()) >+ hoverShell.setVisible(true); >+ } else { >+ if (hoverShell.isVisible()) >+ hoverShell.setVisible(false); >+ } >+ } >+ >+ void setText(String t) { >+ if (t == null) >+ t = ""; //$NON-NLS-1$ >+ if (!t.equals(text)) { >+ Point oldSize = getExtent(); >+ text = t; >+ hoverShell.redraw(); >+ Point newSize = getExtent(); >+ if (!oldSize.equals(newSize)) { >+ Region region = new Region(); >+ region.add(getPolygon(false)); >+ hoverShell.setRegion(region); >+ } >+ } >+ } >+ >+ boolean isVisible() { >+ return hoverShell.isVisible(); >+ } >+ >+ void setLocation(Control control) { >+ if (control != null) { >+ int h = getExtent().y; >+ hoverShell.setLocation(control.toDisplay(-a_OFFSET + a_WIDTH >+ / 2, -h - a_HEIGHT + 1)); >+ } >+ } >+ >+ Point getExtent() { >+ GC gc = new GC(hoverShell); >+ Point e = gc.textExtent(text); >+ gc.dispose(); >+ e.x += h_MARGIN * 2; >+ e.y += h_MARGIN * 2; >+ return e; >+ } >+ } >+ >+ /** >+ * Construct a decorated field which is parented by the specified composite >+ * and has the given style bits. Use the controlCreator to create the >+ * specific kind of control that is decorated inside the field. >+ * >+ * @param parent >+ * the parent of the decorated field. >+ * @param style >+ * the desired style bits for the field. >+ * @param controlCreator >+ * the IControlCreator used to specify the specific kind of >+ * control that is to be decorated. >+ * >+ * @see IControlCreator >+ */ >+ public DecoratedField(Composite parent, int style, >+ IControlCreator controlCreator) { >+ this.form = createForm(parent); >+ this.control = controlCreator.createControl(form, style); >+ >+ addControlListeners(); >+ // Add a dummy decoration on each side to reserve the width needed. >+ addFieldDecoration(new FieldDecoration(null, null), SWT.LEFT | SWT.TOP, >+ true); >+ addFieldDecoration(new FieldDecoration(null, null), >+ SWT.RIGHT | SWT.TOP, true); >+ form.setTabList(new Control[] { control }); >+ >+ // Set up the preferred width of the control and attachments to the >+ // decorations. >+ FormData data = new FormData(); >+ GC gc = new GC(control); >+ gc.setFont(control.getFont()); >+ FontMetrics fontMetrics = gc.getFontMetrics(); >+ gc.dispose(); >+ data.width = Dialog.convertHorizontalDLUsToPixels(fontMetrics, >+ IDialogConstants.ENTRY_FIELD_WIDTH) >+ + 2 * RESERVED_WIDTH; >+ data.left = new FormAttachment(decDatas[LEFT_TOP].label); >+ data.right = new FormAttachment(decDatas[RIGHT_TOP].label); >+ data.top = new FormAttachment(0, 0); >+ control.setLayoutData(data); >+ >+ } >+ >+ /** >+ * Adds an image decoration to the field. >+ * >+ * @param decoration >+ * A FieldDecoration describing the image and description for the >+ * decoration >+ * >+ * @param position >+ * The SWT constant indicating the position of the decoration >+ * relative to the field's control. The position should include >+ * style bits describing both the vertical and horizontal >+ * orientation. <code>SWT.LEFT</code> and >+ * <code>SWT.RIGHT</code> describe the horizontal placement of >+ * the decoration relative to the field, and the constants >+ * <code>SWT.TOP</code> and <code>SWT.BOTTOM</code> describe >+ * the vertical alignment of the decoration relative to the >+ * field. Decorations always appear on either horizontal side of >+ * the field, never above or below it. For example, a decoration >+ * appearing on the left side of the field, at the top, is >+ * specified as SWT.LEFT | SWT.TOP. If an image decoration >+ * already exists in the specified position, it will be replaced >+ * by the one specified. >+ * @param showOnFocus >+ * <code>true</code> if the decoration should only be shown >+ * when the associated control has focus, <code>false</code> if >+ * it should always be shown. >+ * >+ */ >+ public void addFieldDecoration(FieldDecoration decoration, int position, >+ boolean showOnFocus) { >+ final Label label; >+ FormData data; >+ int i = indexForPosition(position); >+ if (decDatas[i] == null) { >+ data = createFormDataForIndex(i); >+ label = new Label(form, SWT.HORIZONTAL | SWT.VERTICAL | SWT.CENTER); >+ label.addMouseTrackListener(new MouseTrackListener() { >+ public void mouseHover(MouseEvent event) { >+ FieldDecorationData decData = (FieldDecorationData) event.widget >+ .getData(); >+ String desc = decData.decoration.getDescription(); >+ if (desc != null) { >+ showHoverText(desc, label); >+ } >+ } >+ >+ public void mouseEnter(MouseEvent event) { >+ } >+ >+ public void mouseExit(MouseEvent event) { >+ hideHover(); >+ } >+ }); >+ decDatas[i] = new FieldDecorationData(decoration, label, data, >+ showOnFocus); >+ } else { >+ label = decDatas[i].label; >+ data = decDatas[i].data; >+ decDatas[i].decoration = decoration; >+ decDatas[i].showOnFocus = showOnFocus; >+ } >+ label.setImage(decDatas[i].decoration.getImage()); >+ label.setData(decDatas[i]); >+ label.setVisible(!showOnFocus); >+ label.setLayoutData(data); >+ } >+ >+ /** >+ * Get the control that is decorated by the receiver. >+ * >+ * @return the Control decorated by the receiver, or <code>null</code> if >+ * none has been created yet. >+ */ >+ public Control getControl() { >+ return control; >+ } >+ >+ /** >+ * Get the control that represents the decorated field. This composite >+ * should be used to lay out the field within its parent. >+ * >+ * @return the Control that should be layed out in the field's parent's >+ * layout. This is typically not the control itself, since >+ * additional controls are used to represent the decorations. >+ */ >+ public Control getLayoutControl() { >+ return form; >+ } >+ >+ /** >+ * Create the parent composite and a form layout that will be used to manage >+ * decorations. >+ */ >+ private Composite createForm(Composite parent) { >+ Composite composite = new Composite(parent, SWT.NO_FOCUS); >+ composite.setLayout(new FormLayout()); >+ composite.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, >+ true, true)); >+ return composite; >+ } >+ >+ /** >+ * Add any listeners needed on the control. >+ */ >+ private void addControlListeners() { >+ control.addDisposeListener(new DisposeListener() { >+ public void widgetDisposed(DisposeEvent event) { >+ if (hover != null) >+ hover.dispose(); >+ } >+ }); >+ control.addFocusListener(new FocusListener() { >+ public void focusGained(FocusEvent event) { >+ controlFocusGained(); >+ } >+ >+ public void focusLost(FocusEvent event) { >+ controlFocusLost(); >+ } >+ >+ }); >+ } >+ >+ /** >+ * Return the index in the array of decoration datas that represents the >+ * specified SWT position. >+ * >+ * @param position >+ * The SWT constant indicating the position of the decoration >+ * relative to the field's control. The position should include >+ * style bits describing both the vertical and horizontal >+ * orientation. <code>SWT.LEFT</code> and >+ * <code>SWT.RIGHT</code> describe the horizontal placement of >+ * the decoration relative to the field, and the constants >+ * <code>SWT.TOP</code> and <code>SWT.BOTTOM</code> describe >+ * the vertical alignment of the decoration relative to the >+ * field. Decorations always appear on either horizontal side of >+ * the field, never above or below it. For example, a decoration >+ * appearing on the left side of the field, at the top, is >+ * specified as SWT.LEFT | SWT.TOP. If an image decoration >+ * already exists in the specified position, it will be replaced >+ * by the one specified. >+ * >+ * @return index the index in the array of decorations that represents the >+ * specified SWT position. If the position is not an expected >+ * position, the index representing the top left position will be >+ * returned. >+ * >+ */ >+ int indexForPosition(int position) { >+ switch (position) { >+ case SWT.LEFT | SWT.BOTTOM: >+ return LEFT_BOTTOM; >+ case SWT.RIGHT | SWT.TOP: >+ return RIGHT_TOP; >+ case SWT.RIGHT | SWT.BOTTOM: >+ return RIGHT_BOTTOM; >+ default: >+ return LEFT_TOP; >+ } >+ } >+ >+ /** >+ * Create a form data that will place the decoration at the specified >+ * position. >+ * >+ * @param position >+ * The SWT constant indicating the position of the decoration >+ * relative to the field's control. The position should include >+ * style bits describing both the vertical and horizontal >+ * orientation. <code>SWT.LEFT</code> and >+ * <code>SWT.RIGHT</code> describe the horizontal placement of >+ * the decoration relative to the field, and the constants >+ * <code>SWT.TOP</code> and <code>SWT.BOTTOM</code> describe >+ * the vertical alignment of the decoration relative to the >+ * field. Decorations always appear on either horizontal side of >+ * the field, never above or below it. For example, a decoration >+ * appearing on the left side of the field, at the top, is >+ * specified as SWT.LEFT | SWT.TOP. If an image decoration >+ * already exists in the specified position, it will be replaced >+ * by the one specified. >+ * >+ */ >+ private FormData createFormDataForIndex(int index) { >+ Assert.isTrue(index >= 0 && index < DECORATION_SLOTS, >+ "Index out of range"); //$NON-NLS-1$ >+ >+ FormData data = new FormData(); >+ data.width = RESERVED_WIDTH; >+ switch (index) { >+ case LEFT_TOP: >+ data.left = new FormAttachment(0, 0); >+ data.top = new FormAttachment(0, 0); >+ return data; >+ case LEFT_BOTTOM: >+ data.left = new FormAttachment(0, 0); >+ data.bottom = new FormAttachment(100, 0); >+ return data; >+ case RIGHT_TOP: >+ data.right = new FormAttachment(100, 0); >+ data.top = new FormAttachment(0, 0); >+ return data; >+ case RIGHT_BOTTOM: >+ data.right = new FormAttachment(100, 0); >+ data.bottom = new FormAttachment(100, 0); >+ return data; >+ } >+ // should never get here, making compiler happy >+ return data; >+ } >+ >+ /** >+ * Show the specified text using the same hover dialog as is used to show >+ * decorator descriptions. Normally, a decoration's description text will be >+ * shown in an info hover over the field's control whenever the mouse hovers >+ * over the decoration. This method can be used to show a decoration's >+ * description text at other times (such as when the control receives >+ * focus), or to show other text associated with the field. >+ * >+ * <p> >+ * If there is currently a hover visible, the hover's text will be replaced >+ * with the specified text. >+ * >+ * @param text >+ * the text to be shown in the info hover, or <code>null</code> >+ * if no text should be shown. >+ */ >+ public void showHoverText(String text) { >+ showHoverText(text, control); >+ } >+ >+ /** >+ * Hide any hover popups that are currently showing on the control. >+ * Normally, a decoration's description text will be shown in an info hover >+ * over the field's control as long as the mouse hovers over the decoration, >+ * and will be hidden when the mouse exits the control. This method can be >+ * used to hide a hover that was shown using <code>showHoverText</code>, >+ * or to programatically hide the current decoration hover. >+ * >+ * <p> >+ * This message has no effect if there is no current hover. >+ * >+ */ >+ public void hideHover() { >+ if (hover != null) { >+ hover.setVisible(false); >+ } >+ } >+ >+ private void controlFocusGained() { >+ for (int i = 0; i < DECORATION_SLOTS; i++) { >+ if (decDatas[i] != null && decDatas[i].showOnFocus) >+ setVisible(decDatas[i], true); >+ } >+ } >+ >+ private void controlFocusLost() { >+ for (int i = 0; i < DECORATION_SLOTS; i++) { >+ if (decDatas[i] != null && decDatas[i].showOnFocus) >+ setVisible(decDatas[i], false); >+ } >+ } >+ >+ /** >+ * Show the specified decoration. This message has no effect if the >+ * decoration is already showing, or was not already added to the field >+ * using <code>addFieldDecoration</code>. >+ * >+ * @param decoration >+ * the decoration to be shown. >+ */ >+ public void showDecoration(FieldDecoration decoration) { >+ FieldDecorationData data = getDecorationData(decoration); >+ if (data == null) >+ return; >+ // record the fact that client would like it to be visible >+ data.visible = true; >+ // even if it is supposed to be shown, if the field does not have focus, >+ // do not show it (yet) >+ if (!data.showOnFocus || control.isFocusControl()) >+ setVisible(data, true); >+ } >+ >+ /** >+ * Hide the specified decoration. This message has no effect if the >+ * decoration is already hidden, or was not already added to the field using >+ * <code>addFieldDecoration</code>. >+ * >+ * @param decoration >+ * the decoration to be hidden. >+ */ >+ public void hideDecoration(FieldDecoration decoration) { >+ FieldDecorationData data = getDecorationData(decoration); >+ if (data == null) >+ return; >+ // store the visibility in the decoration data so internal changes in >+ // visibility don't >+ // accidentally show it. >+ data.visible = false; >+ setVisible(data, false); >+ } >+ >+ private void setVisible(FieldDecorationData decData, boolean visible) { >+ // Don't set it visible if the client has instructed us to hide it. >+ if (visible && decData.visible) >+ decData.label.setVisible(true); >+ else >+ decData.label.setVisible(false); >+ } >+ >+ private FieldDecorationData getDecorationData(FieldDecoration dec) { >+ for (int i = 0; i < DECORATION_SLOTS; i++) { >+ if (decDatas[i] != null && dec == decDatas[i].decoration >+ && decDatas[i].label != null >+ && !decDatas[i].label.isDisposed()) >+ return decDatas[i]; >+ } >+ return null; >+ } >+ >+ private void showHoverText(String text, Control hoverNear) { >+ if (text == null) { >+ hideHover(); >+ return; >+ } >+ >+ if (hover == null) { >+ hover = new Hover(hoverNear.getShell()); >+ } >+ hover.setText(text); >+ hover.setLocation(hoverNear); >+ hover.setVisible(true); >+ } >+} >Index: src/org/eclipse/jface/dialogs/taskassistance/TextContentAdapter.java >=================================================================== >RCS file: src/org/eclipse/jface/dialogs/taskassistance/TextContentAdapter.java >diff -N src/org/eclipse/jface/dialogs/taskassistance/TextContentAdapter.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/dialogs/taskassistance/TextContentAdapter.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,53 @@ >+/******************************************************************************* >+ * Copyright (c) 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.jface.dialogs.taskassistance; >+ >+import org.eclipse.swt.widgets.Control; >+import org.eclipse.swt.widgets.Text; >+ >+/** >+ * A content adapter for SWT Text controls. Used to create a ContentProposalAdapter >+ * for text fields. >+ * >+ * <p> >+ * This API is considered experimental. It is still evolving during 3.2 and is >+ * subject to change. It is being released to obtain feedback from early >+ * adopters. >+ * >+ * @since 3.2 >+ */ >+public class TextContentAdapter implements IControlContentAdapter { >+ >+ /* >+ * (non-Javadoc) >+ * @see org.eclipse.jface.dialogs.taskassistance.IControlContentAdapter#getControlContents(org.eclipse.swt.widgets.Control) >+ */ >+ public String getControlContents(Control control) { >+ return ((Text)control).getText(); >+ } >+ >+ /* >+ * (non-Javadoc) >+ * @see org.eclipse.jface.dialogs.taskassistance.IControlContentAdapter#setControlContents(org.eclipse.swt.widgets.Control, java.lang.String) >+ */ >+ public void setControlContents(Control control, String text) { >+ ((Text)control).setText(text); >+ ((Text)control).setSelection(text.length(), text.length()); >+ } >+ >+ /* >+ * (non-Javadoc) >+ * @see org.eclipse.jface.dialogs.taskassistance.IControlContentAdapter#insertControlContents(org.eclipse.swt.widgets.Control, java.lang.String) >+ */ >+ public void insertControlContents(Control control, String text) { >+ ((Text)control).insert(text); >+ } >+} >Index: src/org/eclipse/jface/dialogs/taskassistance/IContentProposalProvider.java >=================================================================== >RCS file: src/org/eclipse/jface/dialogs/taskassistance/IContentProposalProvider.java >diff -N src/org/eclipse/jface/dialogs/taskassistance/IContentProposalProvider.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/dialogs/taskassistance/IContentProposalProvider.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,48 @@ >+/******************************************************************************* >+ * Copyright (c) 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.jface.dialogs.taskassistance; >+ >+/** >+ * An IContentProposalProvider provides a list of objects that are appropriate >+ * for a textual dialog field, given the field's current content. Proposals may >+ * optionally provide a description. >+ * >+ * <p> >+ * This API is considered experimental. It is still evolving during 3.2 and is >+ * subject to change. It is being released to obtain feedback from early >+ * adopters. >+ * >+ * @since 3.2 >+ */ >+public interface IContentProposalProvider { >+ >+ /** >+ * Return an array of Objects representing the valid content proposals for a >+ * field. >+ * >+ * @return the Objects that represent valid proposals for the field. The >+ * proposal may be a String, or an Object that will be mapped to a >+ * text value using an associated >+ * <code>org.eclipse.jface.viewers.ILabelProvider</code>. >+ */ >+ Object[] getProposals(); >+ >+ /** >+ * Return a String that describes the given proposal in more detail. >+ * >+ * @param proposal >+ * the Object representing a valid proposal >+ * @return a String that further describes the proposal, or >+ * <code>null</code> if there is no description available. >+ */ >+ String getProposalDescription(Object proposal); >+ >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 106199
:
28295
|
28339
|
28372
|
28387
|
28388
| 31221 |
31222
|
31735