### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.ui Index: ui/org/eclipse/jdt/internal/ui/text/java/hover/AbstractAnnotationHover.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/hover/AbstractAnnotationHover.java,v retrieving revision 1.15 diff -u -r1.15 AbstractAnnotationHover.java --- ui/org/eclipse/jdt/internal/ui/text/java/hover/AbstractAnnotationHover.java 21 Feb 2008 15:37:07 -0000 1.15 +++ ui/org/eclipse/jdt/internal/ui/text/java/hover/AbstractAnnotationHover.java 25 Feb 2008 14:39:51 -0000 @@ -34,6 +34,7 @@ import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; @@ -50,6 +51,7 @@ import org.eclipse.jface.action.Action; import org.eclipse.jface.action.ToolBarManager; import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.util.Geometry; import org.eclipse.jface.text.AbstractInformationControl; @@ -123,16 +125,18 @@ private AnnotationInfo fInput; private Composite fParent; - public AnnotationInformationControl(Shell parentShell, int shellStyle, String statusFieldText) { - super(parentShell, shellStyle, statusFieldText); + public AnnotationInformationControl(Shell parentShell, String statusFieldText) { + super(parentShell, statusFieldText); fMarkerAnnotationAccess= new DefaultMarkerAnnotationAccess(); + create(); } - public AnnotationInformationControl(Shell parentShell, int shellStyle, ToolBarManager toolBarManager) { - super(parentShell, shellStyle, toolBarManager); + public AnnotationInformationControl(Shell parentShell, ToolBarManager toolBarManager) { + super(parentShell, toolBarManager); fMarkerAnnotationAccess= new DefaultMarkerAnnotationAccess(); + create(); } /* @@ -153,6 +157,13 @@ deferredCreateContent(fParent); } + /* + * @see org.eclipse.jface.text.IInformationControlExtension#hasContents() + */ + public boolean hasContents() { + return fInput != null; + } + private AnnotationInfo getAnnotationInfo() { return fInput; } @@ -171,6 +182,8 @@ */ protected void createContent(Composite parent) { fParent= new Composite(parent, SWT.NONE); + fParent.setForeground(parent.getForeground()); + fParent.setBackground(parent.getBackground()); fParent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); GridLayout layout= new GridLayout(1, false); layout.verticalSpacing= 0; @@ -217,17 +230,18 @@ if (proposals.length > 0) createCompletionProposalsControl(parent, getAnnotationInfo().document, proposals); - setColor(parent, parent.getForeground(), parent.getBackground()); + setColorAndFont(parent, parent.getForeground(), parent.getBackground(), JFaceResources.getDialogFont()); } - private void setColor(Control control, Color foreground, Color background) { + private void setColorAndFont(Control control, Color foreground, Color background, Font font) { control.setForeground(foreground); control.setBackground(background); - + control.setFont(font); + if (control instanceof Composite) { Control[] children= ((Composite) control).getChildren(); for (int i= 0; i < children.length; i++) { - setColor(children[i], foreground, background); + setColorAndFont(children[i], foreground, background, font); } } } @@ -265,10 +279,10 @@ layout2.verticalSpacing= 2; composite.setLayout(layout2); - Label seperator= new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL); + Label separator= new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL); GridData gridData= new GridData(SWT.FILL, SWT.CENTER, true, false); gridData.horizontalSpan= 2; - seperator.setLayoutData(gridData); + separator.setLayoutData(gridData); Label quickFixImage= new Label(composite, SWT.NONE); quickFixImage.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); @@ -439,7 +453,7 @@ * @see org.eclipse.jdt.internal.ui.text.java.hover.AbstractReusableInformationControlCreator#doCreateInformationControl(org.eclipse.swt.widgets.Shell) */ public IInformationControl doCreateInformationControl(Shell parent) { - return new AnnotationInformationControl(parent, SWT.RESIZE | SWT.TOOL, new ToolBarManager(SWT.FLAT)); + return new AnnotationInformationControl(parent, new ToolBarManager(SWT.FLAT)); } } @@ -454,7 +468,7 @@ * @see org.eclipse.jface.text.IInformationControlCreator#createInformationControl(org.eclipse.swt.widgets.Shell) */ public IInformationControl createInformationControl(Shell parent) { - return new AnnotationInformationControl(parent, SWT.TOOL, EditorsUI.getTooltipAffordanceString()); + return new AnnotationInformationControl(parent, EditorsUI.getTooltipAffordanceString()); } } #P org.eclipse.jface.text Index: src/org/eclipse/jface/text/AbstractInformationControl.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jface.text/src/org/eclipse/jface/text/AbstractInformationControl.java,v retrieving revision 1.1 diff -u -r1.1 AbstractInformationControl.java --- src/org/eclipse/jface/text/AbstractInformationControl.java 20 Feb 2008 15:22:27 -0000 1.1 +++ src/org/eclipse/jface/text/AbstractInformationControl.java 25 Feb 2008 14:39:53 -0000 @@ -10,7 +10,8 @@ *******************************************************************************/ package org.eclipse.jface.text; -import java.util.List; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.ListenerList; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeListener; @@ -19,7 +20,10 @@ import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Cursor; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.GC; @@ -27,46 +31,50 @@ import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Layout; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Slider; import org.eclipse.swt.widgets.ToolBar; -import org.eclipse.core.runtime.ListenerList; - import org.eclipse.jface.action.ToolBarManager; -import org.eclipse.jface.dialogs.PopupDialog; import org.eclipse.jface.internal.text.html.BrowserInformationControl; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.util.Geometry; /** - * The abstract information control can show any content inside a popup window. + * An abstract information control can show any content inside a popup shell. + * The information control can be created in two styles: + * * Additionally it can present either a status line containing a status text or * a toolbar containing toolbar buttons. *

- * Clients must implement {@link #createContent(Composite)} and - * {@link IInformationControl#setInformation(String)} + * Clients must implement {@link #createContent(Composite)}, {@link #hasContents()} and + * {@link IInformationControl#setInformation(String)} and should + * extend {@link #computeTrim()} if they create a content area + * with additional trim (e.g. scrollbars). *

*

* FIXME: Work in progress. Will be modified in order to serve as super class - * for the {@link BrowserInformationControl} as well, see: . + * for the {@link BrowserInformationControl} as well. *

* * @since 3.4 */ public abstract class AbstractInformationControl implements IInformationControl, IInformationControlExtension, IInformationControlExtension3, IInformationControlExtension5 { - - /** The control's popup dialog. */ - private PopupDialog fPopupDialog; + /** The information control's shell. */ + private final Shell fShell; /** Composite containing the content created by subclasses. */ - private Composite fContentComposite; + private final Composite fContentComposite; /** Composite containing the status line content or null if none. */ private Composite fStatusComposite; /** Separator between content and status line or null if none. */ @@ -80,129 +88,308 @@ /** All focus listeners registered to this information control. */ private ListenerList fFocusListeners= new ListenerList(ListenerList.IDENTITY); /** Size constrains, x is the maxWidth and y is the maxHeight, if any. */ - private Point fSizeConstaints; + private Point fSizeConstraints; /** The toolbar manager used by the toolbar or null if none. */ private final ToolBarManager fToolBarManager; - + /** The size of the resize handle if already set, -1 otherwise */ + private int fResizeHandleSize; /** * Creates an abstract information control with the given shell as parent. - * The given shell style is used for popup shell. The control will show a - * status line with the given status field text. + * The control will not be resizable and optionally show a status line with + * the given status field text. + *

+ * Important: Subclasses are required to call {@link #create()} at the end of their constructor. + *

* * @param parentShell the parent of the popup shell - * @param shellStyle style of the popup shell - * @param statusFieldText text to show in the status line + * @param statusFieldText text to show in the status line, or + * null if the status field should be hidden */ - public AbstractInformationControl(Shell parentShell, int shellStyle, String statusFieldText) { - this(parentShell, shellStyle, statusFieldText, null); + public AbstractInformationControl(Shell parentShell, String statusFieldText) { + this(parentShell, SWT.TOOL | SWT.ON_TOP, statusFieldText, null); } /** * Creates an abstract information control with the given shell as parent. - * The given shell style is used for popup shell. The control will show tool - * bar managed by the given tool bar manager. + * The control will be resizable and optionally show a tool bar managed by + * the given tool bar manager. + *

+ * Important: Subclasses are required to call {@link #create()} at the end of their constructor. + *

* * @param parentShell the parent of the popup shell - * @param shellStyle style of the popup shell - * @param toolBarManager the manager of the popup tool bar + * @param toolBarManager the manager of the popup tool bar, or + * null to hide the toolbar */ - public AbstractInformationControl(Shell parentShell, int shellStyle, ToolBarManager toolBarManager) { - this(parentShell, shellStyle, null, toolBarManager); + public AbstractInformationControl(Shell parentShell, ToolBarManager toolBarManager) { + this(parentShell, SWT.TOOL | SWT.ON_TOP | SWT.RESIZE, null, toolBarManager); } /** * Creates an abstract information control with the given shell as parent. - * The given shell style is used for popup shell. The control will show tool - * bar managed by the given tool bar manager. + * The given shell style is used for the popup shell (NO_TRIM will be removed to make sure there's a border). + *

+ * The control will optionally show either a status line or a tool bar. + * At most one of toolBarManager or statusFieldText can be non-null. + *

+ *

+ * Important: Subclasses are required to call {@link #create()} at the end of their constructor. + *

* * @param parentShell the parent of the popup shell * @param shellStyle style of the popup shell - * @param statusFieldText text to show in the status line, if any - * @param toolBarManager the manager of the popup tool bar, if any - */ - private AbstractInformationControl(Shell parentShell, int shellStyle, final String statusFieldText, final ToolBarManager toolBarManager) { + * @param statusFieldText text to show in the status line, or + * null if the status field should be hidden + * @param toolBarManager the manager of the popup tool bar, or + * null to hide the toolbar + * + * @deprecated clients should use one of the public constructors + */ + AbstractInformationControl(Shell parentShell, int shellStyle, final String statusFieldText, final ToolBarManager toolBarManager) { + Assert.isTrue(statusFieldText == null || toolBarManager == null); + fResizeHandleSize= -1; fToolBarManager= toolBarManager; - fPopupDialog= new PopupDialog(parentShell, shellStyle | SWT.NO_FOCUS | SWT.ON_TOP, false, false, false, false, null, null) { - - /* - * @see org.eclipse.jface.dialogs.PopupDialog#createDialogArea(org.eclipse.swt.widgets.Composite) - */ - protected Control createDialogArea(Composite parent) { - Composite composite= new Composite(parent, SWT.NONE); - - composite.setLayoutData(new GridData(GridData.BEGINNING | GridData.FILL_BOTH)); - - GridLayout layout= new GridLayout(); - layout.marginHeight= 0; - layout.marginWidth= 0; - layout.verticalSpacing= 0; - composite.setLayout(layout); - - fContentComposite= new Composite(composite, SWT.NONE); - fContentComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - GridLayout contentLayout= new GridLayout(1, false); - contentLayout.marginHeight= 0; - contentLayout.marginWidth= 0; - fContentComposite.setLayout(contentLayout); - createContent(fContentComposite); - - if (toolBarManager != null || statusFieldText != null) { - fStatusComposite= new Composite(composite, SWT.NONE); - GridData gridData= new GridData(SWT.FILL, SWT.BOTTOM, true, false); - fStatusComposite.setLayoutData(gridData); - GridLayout gridLayout= new GridLayout(1, false); - gridLayout.marginHeight= 0; - gridLayout.marginWidth= 0; - gridLayout.verticalSpacing= 0; - fStatusComposite.setLayout(gridLayout); + + if ((shellStyle & SWT.NO_TRIM) != 0) + shellStyle&= ~(SWT.NO_TRIM | SWT.SHELL_TRIM); // make sure we get the OS border but no other trims + + fShell= new Shell(parentShell, shellStyle); + Display display= fShell.getDisplay(); + Color foreground= display.getSystemColor(SWT.COLOR_INFO_FOREGROUND); + Color background= display.getSystemColor(SWT.COLOR_INFO_BACKGROUND); + setColor(fShell, foreground, background); + + GridLayout layout= new GridLayout(1, false); + layout.marginHeight= 0; + layout.marginWidth= 0; + layout.verticalSpacing= 0; + fShell.setLayout(layout); + + fContentComposite= new Composite(fShell, SWT.NONE); + fContentComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + GridLayout contentLayout= new GridLayout(1, false); + contentLayout.marginHeight= 0; + contentLayout.marginWidth= 0; + fContentComposite.setLayout(contentLayout); + setColor(fContentComposite, foreground, background); + + createStatusComposite(statusFieldText, toolBarManager, foreground, background); + } - createStatusLine(fStatusComposite, statusFieldText, toolBarManager); - } + private void createStatusComposite(final String statusFieldText, final ToolBarManager toolBarManager, Color foreground, Color background) { + if (toolBarManager == null && statusFieldText == null) + return; + + fStatusComposite= new Composite(fShell, SWT.NONE); + GridData gridData= new GridData(SWT.FILL, SWT.BOTTOM, true, false); + fStatusComposite.setLayoutData(gridData); + GridLayout statusLayout= new GridLayout(1, false); + statusLayout.marginHeight= 0; + statusLayout.marginWidth= 0; + statusLayout.verticalSpacing= 1; + fStatusComposite.setLayout(statusLayout); + + fSeparator= new Label(fStatusComposite, SWT.SEPARATOR | SWT.HORIZONTAL); + fSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + if (statusFieldText != null) { + createStatusLabel(statusFieldText, foreground, background); + } else { + createToolBar(toolBarManager); + } + } - return composite; - } + private void createStatusLabel(final String statusFieldText, Color foreground, Color background) { + fStatusLabel= new Label(fStatusComposite, SWT.RIGHT); + fStatusLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + fStatusLabel.setText(statusFieldText); + + FontData[] fontDatas= JFaceResources.getDialogFont().getFontData(); + for (int i= 0; i < fontDatas.length; i++) { + fontDatas[i].setHeight(fontDatas[i].getHeight() * 9 / 10); + } + fStatusLabel.setFont(new Font(fStatusLabel.getDisplay(), fontDatas)); + + fStatusLabel.setForeground(fStatusLabel.getDisplay().getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW)); + fStatusLabel.setBackground(background); + setColor(fStatusComposite, foreground, background); + } + + private void createToolBar(ToolBarManager toolBarManager) { + final Composite bars= new Composite(fStatusComposite, SWT.NONE); + bars.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); + + GridLayout layout= new GridLayout(3, false); + layout.marginHeight= 0; + layout.marginWidth= 0; + layout.horizontalSpacing= 0; + layout.verticalSpacing= 0; + bars.setLayout(layout); + + fToolBar= toolBarManager.createControl(bars); + GridData gd= new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false); + fToolBar.setLayoutData(gd); + + Composite spacer= new Composite(bars, SWT.NONE); + gd= new GridData(SWT.FILL, SWT.FILL, true, true); + gd.widthHint= 0; + gd.heightHint= 0; + spacer.setLayoutData(gd); + + addMoveSupport(spacer); + addResizeSupportIfNecessary(bars); + } - /* - * @see org.eclipse.jface.dialogs.PopupDialog#getBackgroundColorExclusions() - */ - protected List getBackgroundColorExclusions() { - List result= super.getBackgroundColorExclusions(); - - if (fToolBar != null) { - result.add(fStatusComposite); - result.add(fSeparator); - result.add(fToolBar); + private void addResizeSupportIfNecessary(final Composite bars) { + // XXX: workarounds for + // - https://bugs.eclipse.org/bugs/show_bug.cgi?id=219139 : API to add resize grip / grow box in lower right corner of shell + // - https://bugs.eclipse.org/bugs/show_bug.cgi?id=23980 : platform specific shell resize behavior + String platform= SWT.getPlatform(); + final boolean isWin= platform.equals("win32"); //$NON-NLS-1$ + if (!isWin && !platform.equals("gtk")) //$NON-NLS-1$ + return; + + final Canvas resizer= new Canvas(bars, SWT.NONE); + + int size= getResizeHandleSize(bars); + + GridData data= new GridData(SWT.END, SWT.END, false, true); + data.widthHint= size; + data.heightHint= size; + resizer.setLayoutData(data); + resizer.addPaintListener(new PaintListener() { + public void paintControl(PaintEvent e) { + Point s= resizer.getSize(); + int x= s.x - 2; + int y= s.y - 2; + int min= Math.min(x, y); + if (isWin) { + // draw dots + e.gc.setBackground(resizer.getDisplay().getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW)); + int end= min - 1; + for (int i= 0; i <= 2; i++) + for (int j= 0; j <= 2 - i; j++) + e.gc.fillRectangle(end - 4 * i, end - 4 * j, 2, 2); + end--; + e.gc.setBackground(resizer.getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); + for (int i= 0; i <= 2; i++) + for (int j= 0; j <= 2 - i; j++) + e.gc.fillRectangle(end - 4 * i, end - 4 * j, 2, 2); + + } else { + // draw diagonal lines + e.gc.setForeground(resizer.getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); + for (int i= 1; i < min; i+= 4) { + e.gc.drawLine(i, y, x, i); + } + e.gc.setForeground(resizer.getDisplay().getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW)); + for (int i= 2; i < min; i+= 4) { + e.gc.drawLine(i, y, x, i); + } } - - return result; } - - /* - * @see org.eclipse.jface.dialogs.PopupDialog#getForegroundColorExclusions() - */ - protected List getForegroundColorExclusions() { - List result= super.getForegroundColorExclusions(); - - if (fStatusLabel != null) { - result.add(fStatusLabel); - } - - return result; + }); + + resizer.setCursor(new Cursor(resizer.getDisplay(), SWT.CURSOR_SIZESE)); + MouseAdapter resizeSupport= new MouseAdapter() { + private MouseMoveListener fResizeListener; + + public void mouseDown(MouseEvent e) { + Point shellSize= fShell.getSize(); + final int shellX= shellSize.x; + final int shellY= shellSize.y; + Point mouseLoc= resizer.toDisplay(e.x, e.y); + final int mouseX= mouseLoc.x; + final int mouseY= mouseLoc.y; + fResizeListener= new MouseMoveListener() { + public void mouseMove(MouseEvent e2) { + Point mouseLoc2= resizer.toDisplay(e2.x, e2.y); + int dx= mouseLoc2.x - mouseX; + int dy= mouseLoc2.y - mouseY; + setSize(shellX + dx, shellY + dy); + } + }; + resizer.addMouseMoveListener(fResizeListener); + } + + public void mouseUp(MouseEvent e) { + resizer.removeMouseMoveListener(fResizeListener); + fResizeListener= null; } }; + resizer.addMouseListener(resizeSupport); + } - // Force create early so that listeners can be added at all times with API. - fPopupDialog.create(); + private int getResizeHandleSize(Composite parent) { + if (fResizeHandleSize == -1) { + Slider sliderV= new Slider(parent, SWT.VERTICAL); + Slider sliderH= new Slider(parent, SWT.HORIZONTAL); + int width= sliderV.computeSize(SWT.DEFAULT, SWT.DEFAULT).x; + int height= sliderH.computeSize(SWT.DEFAULT, SWT.DEFAULT).y; + sliderV.dispose(); + sliderH.dispose(); + fResizeHandleSize= Math.min(width, height); + } + + return fResizeHandleSize; } + + /** + * Adds support to move the shell by dragging the given control. + * + * @param control the control that can be used to move the shell + */ + private void addMoveSupport(final Control control) { + MouseAdapter moveSupport= new MouseAdapter() { + private MouseMoveListener fMoveListener; + public void mouseDown(MouseEvent e) { + Point shellLoc= fShell.getLocation(); + final int shellX= shellLoc.x; + final int shellY= shellLoc.y; + Point mouseLoc= control.toDisplay(e.x, e.y); + final int mouseX= mouseLoc.x; + final int mouseY= mouseLoc.y; + fMoveListener= new MouseMoveListener() { + public void mouseMove(MouseEvent e2) { + Point mouseLoc2= control.toDisplay(e2.x, e2.y); + int dx= mouseLoc2.x - mouseX; + int dy= mouseLoc2.y - mouseY; + fShell.setLocation(shellX + dx, shellY + dy); + } + }; + control.addMouseMoveListener(fMoveListener); + } + + public void mouseUp(MouseEvent e) { + control.removeMouseMoveListener(fMoveListener); + fMoveListener= null; + } + }; + control.addMouseListener(moveSupport); + } + + /** + * Utility to set the foreground and the background color of the given + * control + * + * @param control the control to modify + * @param foreground the color to use for the foreground + * @param background the color to use for the background + */ + private static void setColor(Control control, Color foreground, Color background) { + control.setForeground(foreground); + control.setBackground(background); + } + /** * The shell of the popup window. * * @return the shell used for the popup window */ - protected Shell getShell() { - return fPopupDialog.getShell(); + protected final Shell getShell() { + return fShell; } /** @@ -216,49 +403,77 @@ } /** + * Creates the content of this information control. Subclasses must call + * this method at the end of their constructor(s). + */ + public final void create() { + createContent(fContentComposite); + } + + /** * Creates the content of the popup window. + *

+ * Implementors will usually take over {@link Composite#getBackground()} and + * {@link Composite#getForeground()} from parent. + *

+ *

+ * Implementors are expected to consider {@link #isResizable()}: If + * true, they should show scrollbars if their content may + * exceed the size of the information control. If false, + * they should never show scrollbars. + *

* * @param parent the container of the content */ protected abstract void createContent(Composite parent); + + /** + * Returns whether the information control is resizable. + * + * @return true if the information control is resizable, + * false if it is not resizable. + */ + public boolean isResizable() { + return (fShell.getStyle() & SWT.RESIZE) != 0; + } /* * @see IInformationControl#setVisible(boolean) */ public void setVisible(boolean visible) { - if (visible) - fPopupDialog.open(); - else - fPopupDialog.getShell().setVisible(false); + if (fShell.isVisible() == visible) + return; + + fShell.setVisible(visible); } /* * @see IInformationControl#dispose() */ public void dispose() { - fPopupDialog.close(); - fPopupDialog= null; + if (fShell != null && !fShell.isDisposed()) + fShell.dispose(); } /* * @see IInformationControl#setSize(int, int) */ public void setSize(int width, int height) { - fPopupDialog.getShell().setSize(width, height); + fShell.setSize(width, height); } /* * @see IInformationControl#setLocation(Point) */ public void setLocation(Point location) { - fPopupDialog.getShell().setLocation(location); + fShell.setLocation(location); } /* * @see IInformationControl#setSizeConstraints(int, int) */ public void setSizeConstraints(int maxWidth, int maxHeight) { - fSizeConstaints= new Point(maxWidth, maxHeight); + fSizeConstraints= new Point(maxWidth, maxHeight); } /** @@ -268,7 +483,7 @@ * @see #setSizeConstraints(int, int) */ protected final Point getSizeConstraints() { - return fSizeConstaints != null ? Geometry.copy(fSizeConstaints) : null; + return fSizeConstraints != null ? Geometry.copy(fSizeConstraints) : null; } /* @@ -277,54 +492,24 @@ public Point computeSizeHint() { Point constrains= getSizeConstraints(); if (constrains == null) - return fPopupDialog.getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT, true); + return fShell.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); - return fPopupDialog.getShell().computeSize(constrains.x, constrains.y, true); + return fShell.computeSize(constrains.x, constrains.y, true); } - /* + /** + * Computes the trim (status text and tool bar are considered as trim). + * Subclasses can extend this method to add additional trim (e.g. scroll + * bars for resizable information controls). + * * @see org.eclipse.jface.text.IInformationControlExtension3#computeTrim() */ public Rectangle computeTrim() { - Shell shell= fPopupDialog.getShell(); - Rectangle trim= shell.computeTrim(0, 0, 0, 0); - - if (fToolBar != null) { - trim.height+= fSeparator.computeSize(SWT.DEFAULT, SWT.DEFAULT).y; - trim.height+= fToolBar.computeSize(SWT.DEFAULT, SWT.DEFAULT).y; - } else if (fStatusLabel != null) { - trim.height+= fSeparator.computeSize(SWT.DEFAULT, SWT.DEFAULT).y; - trim.height+= fStatusLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT).y; - } + Rectangle trim= fShell.computeTrim(0, 0, 0, 0); - // Popup dialog adds a 1 pixel border when SWT.NO_TRIM is set: - Layout layout= shell.getLayout(); - if (layout instanceof GridLayout) { - GridLayout gridLayout= (GridLayout) layout; - int left= gridLayout.marginLeft + gridLayout.marginWidth; - int top= gridLayout.marginTop + gridLayout.marginHeight; - trim.x-= left; - trim.y-= top; - trim.width+= left + gridLayout.marginRight + gridLayout.marginWidth; - trim.height+= top + gridLayout.marginBottom + gridLayout.marginHeight; - } - - return computeTrim(trim); - } + if (fStatusComposite != null) + trim.height+= fStatusComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT).y; - /** - * Compute the trim based on the given trim. - *

- * Subclasses can either adapt the given trim according to there needs or - * overwrite {@link #computeTrim()} directly. - *

- * - * @param trim the proposed trim size - * @return the trim of the popup dialogs - * - * @see org.eclipse.jface.text.IInformationControlExtension3#computeTrim() - */ - protected Rectangle computeTrim(Rectangle trim) { return trim; } @@ -332,7 +517,7 @@ * @see org.eclipse.jface.text.IInformationControlExtension3#getBounds() */ public Rectangle getBounds() { - return fPopupDialog.getShell().getBounds(); + return fShell.getBounds(); } /* @@ -353,14 +538,14 @@ * @see IInformationControl#addDisposeListener(DisposeListener) */ public void addDisposeListener(DisposeListener listener) { - fPopupDialog.getShell().addDisposeListener(listener); + fShell.addDisposeListener(listener); } /* * @see IInformationControl#removeDisposeListener(DisposeListener) */ public void removeDisposeListener(DisposeListener listener) { - fPopupDialog.getShell().removeDisposeListener(listener); + fShell.removeDisposeListener(listener); } /* @@ -381,15 +566,19 @@ * @see IInformationControl#isFocusControl() */ public boolean isFocusControl() { - Shell shell= fPopupDialog.getShell(); - return shell.getDisplay().getActiveShell() == shell; + return fShell.getDisplay().getActiveShell() == fShell; } - /* + /** + * This default implementation sets the focus on the popup shell. + * Subclasses can override or extend. + * * @see IInformationControl#setFocus() */ public void setFocus() { - fPopupDialog.getShell().forceFocus(); + boolean focusTaken= fShell.setFocus(); + if (!focusTaken) + fShell.forceFocus(); } /* @@ -411,8 +600,8 @@ } } }; - getShell().addListener(SWT.Deactivate, fShellListener); - getShell().addListener(SWT.Activate, fShellListener); + fShell.addListener(SWT.Deactivate, fShellListener); + fShell.addListener(SWT.Activate, fShellListener); } fFocusListeners.add(listener); } @@ -423,26 +612,18 @@ public void removeFocusListener(FocusListener listener) { fFocusListeners.remove(listener); if (fFocusListeners.isEmpty()) { - getShell().removeListener(SWT.Activate, fShellListener); - getShell().removeListener(SWT.Deactivate, fShellListener); + fShell.removeListener(SWT.Activate, fShellListener); + fShell.removeListener(SWT.Deactivate, fShellListener); fShellListener= null; } } /* - * @see IInformationControlExtension#hasContents() - */ - public boolean hasContents() { - return true; - } - - /* * @see org.eclipse.jface.text.IInformationControlExtension5#containsControl(org.eclipse.swt.widgets.Control) */ public boolean containsControl(Control control) { do { - Shell popupShell= fPopupDialog.getShell(); - if (control == popupShell) + if (control == fShell) return true; if (control instanceof Shell) return false; @@ -455,8 +636,7 @@ * @see org.eclipse.jface.text.IInformationControlExtension5#isVisible() */ public boolean isVisible() { - Shell popupShell= fPopupDialog.getShell(); - return popupShell != null && !popupShell.isDisposed() && popupShell.isVisible(); + return fShell != null && !fShell.isDisposed() && fShell.isVisible(); } /* @@ -466,8 +646,13 @@ return true; } - /* - * @see org.eclipse.jface.text.IInformationControlExtension5#computeSizeConstraints(int, int) + /** + * Computes the size constraints based on the + * {@link JFaceResources#getDialogFont() dialog font}. Subclasses can + * override or extend. + * + * @see org.eclipse.jface.text.IInformationControlExtension5#computeSizeConstraints(int, + * int) */ public Point computeSizeConstraints(int widthInChars, int heightInChars) { GC gc= new GC(fContentComposite); @@ -478,63 +663,5 @@ return new Point(widthInChars * width, heightInChars * height); } - - private void createStatusLine(Composite parent, String statusFieldText, ToolBarManager toolBarManager) { - fSeparator= new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL | SWT.LINE_DOT); - fSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - if (toolBarManager != null) { - fToolBar= toolBarManager.createControl(parent); - fToolBar.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); - - addMoveSupport(parent); - } else { - fStatusLabel= new Label(parent, SWT.RIGHT); - fStatusLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - fStatusLabel.setText(statusFieldText); - - FontData[] fontDatas= fStatusLabel.getFont().getFontData(); - for (int i= 0; i < fontDatas.length; i++) { - fontDatas[i].setHeight(fontDatas[i].getHeight() * 9 / 10); - } - fStatusLabel.setFont(new Font(fStatusLabel.getDisplay(), fontDatas)); - fStatusLabel.setForeground(fStatusLabel.getDisplay().getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW)); - } - } - - /** - * Adds support to move the shell by dragging the given control. - * - * @param control the control that can be used to move the shell - */ - private void addMoveSupport(final Control control) { - MouseAdapter moveSupport= new MouseAdapter() { - private MouseMoveListener fMoveListener; - - public void mouseDown(MouseEvent e) { - Point shellLoc= fPopupDialog.getShell().getLocation(); - final int shellX= shellLoc.x; - final int shellY= shellLoc.y; - Point mouseLoc= control.toDisplay(e.x, e.y); - final int mouseX= mouseLoc.x; - final int mouseY= mouseLoc.y; - fMoveListener= new MouseMoveListener() { - public void mouseMove(MouseEvent e2) { - Point mouseLoc2= control.toDisplay(e2.x, e2.y); - int dx= mouseLoc2.x - mouseX; - int dy= mouseLoc2.y - mouseY; - fPopupDialog.getShell().setLocation(shellX + dx, shellY + dy); - } - }; - control.addMouseMoveListener(fMoveListener); - } - - public void mouseUp(MouseEvent e) { - control.removeMouseMoveListener(fMoveListener); - fMoveListener= null; - } - }; - control.addMouseListener(moveSupport); - } } Index: src/org/eclipse/jface/text/DefaultInformationControl.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jface.text/src/org/eclipse/jface/text/DefaultInformationControl.java,v retrieving revision 1.42 diff -u -r1.42 DefaultInformationControl.java --- src/org/eclipse/jface/text/DefaultInformationControl.java 20 Feb 2008 15:33:37 -0000 1.42 +++ src/org/eclipse/jface/text/DefaultInformationControl.java 25 Feb 2008 14:39:53 -0000 @@ -12,6 +12,8 @@ import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Drawable; import org.eclipse.swt.graphics.Point; @@ -21,6 +23,7 @@ import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; +import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.util.Geometry; @@ -33,7 +36,7 @@ * * @since 2.0 */ -public class DefaultInformationControl extends AbstractInformationControl { +public class DefaultInformationControl extends AbstractInformationControl implements DisposeListener { /** * An information presenter determines the style presentation @@ -103,15 +106,15 @@ /** The control's text widget */ private StyledText fText; /** The information presenter */ - private IInformationPresenter fPresenter; + private final IInformationPresenter fPresenter; /** A cached text presentation */ - private TextPresentation fPresentation= new TextPresentation(); + private final TextPresentation fPresentation= new TextPresentation(); /** - * Style to use for the text control. + * Additional styles to use for the text control. * @since 3.4 */ - private final int fTextStyle; + private final int fAdditionalTextStyles; /** * Creates a default information control with the given shell as parent. The given @@ -141,44 +144,98 @@ * @since 3.0 */ public DefaultInformationControl(Shell parentShell, int shellStyle, final int style, IInformationPresenter presenter, String statusFieldText) { - super(parentShell, shellStyle, statusFieldText); - fTextStyle= style; + super(parentShell, SWT.NO_FOCUS | SWT.ON_TOP | shellStyle, statusFieldText, null); + fAdditionalTextStyles= style; fPresenter= presenter; + create(); } - + /** * Creates a default information control with the given shell as parent. The given - * information presenter is used to process the information to be displayed. The given - * styles are applied to the created styled text widget. + * information presenter is used to process the information to be displayed. + * The styled text widget is read only, multi-line, plus the styles from textStyles. * * @param parent the parent shell - * @param style the additional styles for the styled text widget + * @param textStyles the additional styles for the styled text widget * @param presenter the presenter to be used */ - public DefaultInformationControl(Shell parent,int style, IInformationPresenter presenter) { - this(parent, SWT.TOOL | SWT.NO_TRIM, style, presenter); + public DefaultInformationControl(Shell parent, int textStyles, IInformationPresenter presenter) { + this(parent, textStyles, presenter, null); } /** * Creates a default information control with the given shell as parent. The given - * information presenter is used to process the information to be displayed. The given - * styles are applied to the created styled text widget. + * information presenter is used to process the information to be displayed. + * The styled text widget is read only, multi-line, plus the styles from textStyles. * * @param parent the parent shell - * @param style the additional styles for the styled text widget + * @param textStyles the additional styles for the styled text widget * @param presenter the presenter to be used * @param statusFieldText the text to be used in the optional status field * or null if the status field should be hidden * @since 3.0 */ - public DefaultInformationControl(Shell parent,int style, IInformationPresenter presenter, String statusFieldText) { - this(parent, SWT.TOOL | SWT.NO_TRIM, style, presenter, statusFieldText); + public DefaultInformationControl(Shell parent, int textStyles, IInformationPresenter presenter, String statusFieldText) { + super(parent, statusFieldText); + fAdditionalTextStyles= textStyles; + fPresenter= presenter; + create(); } +// FIXME: +// WRAP style looks ugly when resizable (only vertical scroll bar), and has +// strange effects with the current implementation: setInformation(), setVisible(), +// and computeSizeHint() all don't respect trim and size hints, e.g. setVisible overrides +// minimum size from information control manager. +// When this is sorted out, deprecate the constructors above and replace with something like +// * @deprecated use +// * {@link #DefaultInformationControl(Shell, DefaultInformationControl.IInformationPresenter, String)} +// * for a tooltip-like information control or +// * {@link #DefaultInformationControl(Shell, DefaultInformationControl.IInformationPresenter, ToolBarManager)} +// * for a resizable information control + + +// /** +// * Creates a default information control with the given shell as parent. The +// * given information presenter is used to process the information to be +// * displayed. The styled text widget is read only, multi-line, and wraps. +// * +// * @param parent the parent shell +// * @param presenter the presenter to be used, or null if no presenter should be used +// * @param statusFieldText the text to be used in the optional status field +// * or null if the status field should be hidden +// * @since 3.4 +// */ +// public DefaultInformationControl(Shell parent, IInformationPresenter presenter, String statusFieldText) { +// super(parent, statusFieldText); +// fAdditionalTextStyles= SWT.WRAP; +// fPresenter= presenter; +// create(); +// } +// +// /** +// * Creates a resizable default information control with the given shell as +// * parent. The given information presenter is used to process the +// * information to be displayed. The styled text widget is read only, +// * multi-line, wraps, and has scroll bars. +// * +// * @param parent the parent shell +// * @param presenter the presenter to be used, or null if no presenter should be used +// * @param toolBarManager the manager of the popup tool bar, or +// * null to hide the toolbar +// * @since 3.4 +// */ +// public DefaultInformationControl(Shell parent, IInformationPresenter presenter, ToolBarManager toolBarManager) { +// super(parent, toolBarManager); +// fAdditionalTextStyles= SWT.WRAP | SWT.V_SCROLL | SWT.H_SCROLL; +// fPresenter= presenter; +// create(); +// } + /** * Creates a default information control with the given shell as parent. * No information presenter is used to process the information - * to be displayed. No additional styles are applied to the styled text widget. + * to be displayed. The styled text widget is read only and multi-line, but does not wrap. * * @param parent the parent shell */ @@ -189,7 +246,7 @@ /** * Creates a default information control with the given shell as parent. The given * information presenter is used to process the information to be displayed. - * No additional styles are applied to the styled text widget. + * The styled text widget is read only and multi-line, but does not wrap. * * @param parent the parent shell * @param presenter the presenter to be used @@ -198,11 +255,15 @@ this(parent, SWT.NONE, presenter); } + /* * @see org.eclipse.jface.text.AbstractInformationControl#createContent(org.eclipse.swt.widgets.Composite) */ protected void createContent(Composite parent) { - fText= new StyledText(parent, SWT.MULTI | SWT.READ_ONLY | fTextStyle); + fText= new StyledText(parent, SWT.MULTI | SWT.READ_ONLY | fAdditionalTextStyles); + fText.setForeground(parent.getForeground()); + fText.setBackground(parent.getBackground()); + fText.setFont(JFaceResources.getDialogFont()); GridData gd= new GridData(GridData.BEGINNING | GridData.FILL_BOTH); gd.horizontalIndent= INNER_BORDER; gd.verticalIndent= INNER_BORDER; @@ -268,12 +329,12 @@ return getShell().computeSize(widthHint, SWT.DEFAULT, true); } - + /* - * @see org.eclipse.jface.text.AbstractInformationControl#computeTrim(org.eclipse.swt.graphics.Rectangle) + * @see org.eclipse.jface.text.AbstractInformationControl#computeTrim() */ - protected Rectangle computeTrim(Rectangle trim) { - return Geometry.add(trim, fText.computeTrim(0, 0, 0, 0)); + public Rectangle computeTrim() { + return Geometry.add(super.computeTrim(), fText.computeTrim(0, 0, 0, 0)); } /* @@ -293,11 +354,18 @@ } /* - * @see IInformationControl#setFocus() + * @see IInformationControlExtension#hasContents() */ - public void setFocus() { - super.setFocus(); - fText.setFocus(); + public boolean hasContents() { + return fText.getCharCount() > 0; } + /** + * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent) + * @since 3.0 + * @deprecated As of 3.2, no longer used and called + */ + public void widgetDisposed(DisposeEvent event) { + } + }