| /******************************************************************************* |
| * Copyright (c) 2004, 2014 Tasktop Technologies and others. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * https://www.eclipse.org/legal/epl-2.0 |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Tasktop Technologies - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.mylyn.internal.tasks.ui.editors; |
| |
| import java.lang.reflect.Field; |
| import java.text.DateFormat; |
| import java.util.Date; |
| |
| import org.eclipse.jface.layout.GridDataFactory; |
| import org.eclipse.jface.layout.GridLayoutFactory; |
| import org.eclipse.jface.resource.JFaceResources; |
| import org.eclipse.jface.text.ITextOperationTarget; |
| import org.eclipse.jface.text.TextViewer; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.mylyn.commons.ui.CommonUiUtil; |
| import org.eclipse.mylyn.commons.ui.PlatformUiUtil; |
| import org.eclipse.mylyn.commons.ui.compatibility.CommonThemes; |
| import org.eclipse.mylyn.commons.workbench.editors.CommonTextSupport; |
| import org.eclipse.mylyn.commons.workbench.forms.CommonFormUtil; |
| import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal; |
| import org.eclipse.mylyn.internal.tasks.ui.wizards.NewAttachmentWizardDialog; |
| import org.eclipse.mylyn.internal.tasks.ui.wizards.TaskAttachmentWizard.Mode; |
| import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentSource; |
| import org.eclipse.mylyn.tasks.core.data.TaskAttribute; |
| import org.eclipse.mylyn.tasks.core.data.TaskAttributeMapper; |
| import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPage; |
| import org.eclipse.mylyn.tasks.ui.editors.TaskFormPage; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.custom.CCombo; |
| import org.eclipse.swt.custom.CTabFolder; |
| import org.eclipse.swt.custom.ScrolledComposite; |
| import org.eclipse.swt.events.DisposeEvent; |
| import org.eclipse.swt.events.DisposeListener; |
| import org.eclipse.swt.events.MouseEvent; |
| import org.eclipse.swt.events.MouseWheelListener; |
| import org.eclipse.swt.events.PaintEvent; |
| import org.eclipse.swt.events.PaintListener; |
| import org.eclipse.swt.graphics.Color; |
| import org.eclipse.swt.graphics.Font; |
| import org.eclipse.swt.graphics.FontData; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.layout.RowLayout; |
| 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.Listener; |
| import org.eclipse.swt.widgets.Menu; |
| import org.eclipse.swt.widgets.ScrollBar; |
| import org.eclipse.swt.widgets.Scrollable; |
| import org.eclipse.swt.widgets.Widget; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.actions.ActionFactory; |
| import org.eclipse.ui.forms.IManagedForm; |
| import org.eclipse.ui.forms.editor.IFormPage; |
| import org.eclipse.ui.forms.widgets.ExpandableComposite; |
| import org.eclipse.ui.forms.widgets.FormToolkit; |
| import org.eclipse.ui.forms.widgets.ScrolledForm; |
| import org.eclipse.ui.forms.widgets.Section; |
| import org.eclipse.ui.forms.widgets.SharedScrolledComposite; |
| import org.eclipse.ui.internal.WorkbenchPage; |
| import org.eclipse.ui.internal.forms.widgets.FormUtil; |
| |
| /** |
| * @author Steffen Pingel |
| * @author Leo Dos Santos |
| */ |
| public class EditorUtil { |
| |
| private static final int PAGE_H_SCROLL_INCREMENT = 64; |
| |
| public static final int HEADER_COLUMN_MARGIN = 6; |
| |
| // public static final String DATE_FORMAT = "yyyy-MM-dd"; |
| // |
| // public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm"; |
| |
| static final String KEY_MARKER = "marker"; //$NON-NLS-1$ |
| |
| static final String KEY_TEXT_VIEWER = "textViewer"; //$NON-NLS-1$ |
| |
| public static final int MAXIMUM_HEIGHT = 140; |
| |
| public static final int MAXIMUM_WIDTH = 300; |
| |
| // XXX why is this required? |
| public static final Font TEXT_FONT = JFaceResources.getDefaultFont(); |
| |
| public static final String KEY_TOGGLE_TO_MAXIMIZE_ACTION = "maximizeAction"; //$NON-NLS-1$ |
| |
| static boolean canDoGlobalAction(String actionId, TextViewer textViewer) { |
| if (actionId.equals(ActionFactory.CUT.getId())) { |
| return textViewer.canDoOperation(ITextOperationTarget.CUT); |
| } else if (actionId.equals(ActionFactory.COPY.getId())) { |
| return textViewer.canDoOperation(ITextOperationTarget.COPY); |
| } else if (actionId.equals(ActionFactory.PASTE.getId())) { |
| return textViewer.canDoOperation(ITextOperationTarget.PASTE); |
| } else if (actionId.equals(ActionFactory.DELETE.getId())) { |
| return textViewer.canDoOperation(ITextOperationTarget.DELETE); |
| } else if (actionId.equals(ActionFactory.UNDO.getId())) { |
| return textViewer.canDoOperation(ITextOperationTarget.UNDO); |
| } else if (actionId.equals(ActionFactory.REDO.getId())) { |
| return textViewer.canDoOperation(ITextOperationTarget.REDO); |
| } else if (actionId.equals(ActionFactory.SELECT_ALL.getId())) { |
| return textViewer.canDoOperation(ITextOperationTarget.SELECT_ALL); |
| } |
| return false; |
| } |
| |
| /** |
| * @deprecated use {@link CommonTextSupport#canPerformAction(String, Control)} instead |
| */ |
| @Deprecated |
| public static boolean canPerformAction(String actionId, Control focusControl) { |
| return CommonTextSupport.canPerformAction(actionId, focusControl); |
| } |
| |
| /** |
| * @deprecated use {@link CommonTextSupport#doAction(String, Control)} instead |
| */ |
| @Deprecated |
| public static void doAction(String actionId, Control focusControl) { |
| CommonTextSupport.doAction(actionId, focusControl); |
| } |
| |
| private static Control findControl(Composite composite, String key) { |
| if (!composite.isDisposed()) { |
| for (Control child : composite.getChildren()) { |
| if (key.equals(getMarker(child))) { |
| return child; |
| } |
| if (child instanceof Composite) { |
| Control found = findControl((Composite) child, key); |
| if (found != null) { |
| return found; |
| } |
| } |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Scroll to a specified piece of text |
| * |
| * @param control |
| * The StyledText to scroll to |
| */ |
| public static void focusOn(ScrolledForm form, Control control) { |
| int pos = 0; |
| control.setEnabled(true); |
| control.setFocus(); |
| control.forceFocus(); |
| while (control != null && control != form.getBody()) { |
| pos += control.getLocation().y; |
| control = control.getParent(); |
| } |
| |
| pos = pos - 60; // form.getOrigin().y; |
| if (!form.getBody().isDisposed()) { |
| form.setOrigin(0, pos); |
| } |
| } |
| |
| static DateFormat getDateFormat() { |
| return DateFormat.getDateInstance(DateFormat.MEDIUM); |
| } |
| |
| static String formatDate(Date date) { |
| return getDateFormat().format(date); |
| } |
| |
| static String formatDateTime(Date date) { |
| return getDateTimeFormat().format(date); |
| } |
| |
| static DateFormat getDateTimeFormat() { |
| return DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT); |
| } |
| |
| public static Control getFocusControl(IFormPage page) { |
| if (page == null) { |
| return null; |
| } |
| IManagedForm form = page.getManagedForm(); |
| if (form == null) { |
| return null; |
| } |
| Control control = form.getForm(); |
| if (control == null || control.isDisposed()) { |
| return null; |
| } |
| Display display = control.getDisplay(); |
| Control focusControl = display.getFocusControl(); |
| if (focusControl == null || focusControl.isDisposed()) { |
| return null; |
| } |
| return focusControl; |
| } |
| |
| public static String getMarker(Widget widget) { |
| return (String) widget.getData(KEY_MARKER); |
| } |
| |
| /** |
| * @deprecated use {@link CommonTextSupport#getTextViewer(Widget)} instead |
| */ |
| @Deprecated |
| public static TextViewer getTextViewer(Widget widget) { |
| return CommonTextSupport.getTextViewer(widget); |
| } |
| |
| public static NewAttachmentWizardDialog openNewAttachmentWizard(final AbstractTaskEditorPage page, Mode mode, |
| AbstractTaskAttachmentSource source) { |
| TaskAttributeMapper mapper = page.getModel().getTaskData().getAttributeMapper(); |
| TaskAttribute attribute = mapper.createTaskAttachment(page.getModel().getTaskData()); |
| final NewAttachmentWizardDialog dialog = TasksUiInternal.openNewAttachmentWizard(page.getSite().getShell(), |
| page.getTaskRepository(), page.getTask(), attribute, mode, source); |
| dialog.getShell().addDisposeListener(new DisposeListener() { |
| |
| public void widgetDisposed(DisposeEvent e) { |
| if (dialog.getReturnCode() == Window.OK) { |
| page.getTaskEditor().refreshPages(); |
| } |
| } |
| |
| }); |
| return dialog; |
| } |
| |
| /** |
| * Selects the given object in the editor. |
| * |
| * @param o |
| * The object to be selected. |
| * @param highlight |
| * Whether or not the object should be highlighted. |
| */ |
| public static boolean reveal(ScrolledForm form, String key) { |
| Control control = findControl(form.getBody(), key); |
| if (control != null) { |
| // expand all children |
| if (control instanceof ExpandableComposite) { |
| ExpandableComposite ex = (ExpandableComposite) control; |
| if (!ex.isExpanded()) { |
| CommonFormUtil.setExpanded(ex, true); |
| } |
| } |
| |
| // expand all parents of control |
| Composite comp = control.getParent(); |
| while (comp != null) { |
| if (comp instanceof Section) { |
| if (!((Section) comp).isExpanded()) { |
| ((Section) comp).setExpanded(true); |
| } |
| } else if (comp instanceof ExpandableComposite) { |
| ExpandableComposite ex = (ExpandableComposite) comp; |
| if (!ex.isExpanded()) { |
| CommonFormUtil.setExpanded(ex, true); |
| } |
| |
| // HACK: This is necessary |
| // due to a bug in SWT's ExpandableComposite. |
| // 165803: Expandable bars should expand when clicking anywhere |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?taskId=165803 |
| if (ex.getData() != null && ex.getData() instanceof Composite) { |
| ((Composite) ex.getData()).setVisible(true); |
| } |
| } |
| comp = comp.getParent(); |
| } |
| focusOn(form, control); |
| } |
| return true; |
| } |
| |
| /** |
| * @deprecated Use {@link CommonUiUtil#setEnabled(Composite,boolean)} instead |
| */ |
| @Deprecated |
| public static void setEnabledState(Composite composite, boolean enabled) { |
| CommonUiUtil.setEnabled(composite, enabled); |
| } |
| |
| public static void setMarker(Widget widget, String text) { |
| widget.setData(KEY_MARKER, text); |
| } |
| |
| /** |
| * @deprecated use {@link CommonTextSupport#setTextViewer(Widget, TextViewer)} instead |
| */ |
| @Deprecated |
| public static void setTextViewer(Widget widget, TextViewer textViewer) { |
| CommonTextSupport.setTextViewer(widget, textViewer); |
| } |
| |
| /** |
| * Programmatically expand the provided ExpandableComposite, using reflection to fire the expansion listeners (see |
| * bug#70358) |
| * |
| * @param comp |
| * @deprecated Use {@link CommonFormUtil#setExpanded(ExpandableComposite,boolean)} instead |
| */ |
| @Deprecated |
| public static void toggleExpandableComposite(boolean expanded, ExpandableComposite comp) { |
| CommonFormUtil.setExpanded(comp, expanded); |
| } |
| |
| /** |
| * @deprecated Use {@link CommonFormUtil#disableScrollingOnFocus(ScrolledForm)} instead |
| */ |
| @Deprecated |
| public static void disableScrollingOnFocus(ScrolledForm form) { |
| CommonFormUtil.disableScrollingOnFocus(form); |
| } |
| |
| /** |
| * @deprecated Use {@link CommonFormUtil#ensureVisible(Control)} instead |
| */ |
| @Deprecated |
| public static void ensureVisible(Control control) { |
| CommonFormUtil.ensureVisible(control); |
| } |
| |
| // copied from Section.reflow() |
| public static void reflow(Control control) { |
| Composite c = control.getParent(); |
| while (c != null) { |
| c.setRedraw(false); |
| c = c.getParent(); |
| if (c instanceof SharedScrolledComposite) { |
| break; |
| } |
| } |
| c = control.getParent(); |
| while (c != null) { |
| c.layout(true); |
| c = c.getParent(); |
| if (c instanceof SharedScrolledComposite) { |
| ((SharedScrolledComposite) c).reflow(true); |
| break; |
| } |
| } |
| c = control.getParent(); |
| while (c != null) { |
| c.setRedraw(true); |
| c = c.getParent(); |
| if (c instanceof SharedScrolledComposite) { |
| break; |
| } |
| } |
| } |
| |
| public static Composite getLayoutAdvisor(AbstractTaskEditorPage page) { |
| Composite layoutAdvisor = page.getEditorComposite(); |
| do { |
| layoutAdvisor = layoutAdvisor.getParent(); |
| } while (!(layoutAdvisor instanceof CTabFolder || layoutAdvisor.getClass() |
| .getName() |
| .equals("org.eclipse.e4.ui.widgets.CTabFolder"))); //$NON-NLS-1$ |
| return layoutAdvisor.getParent(); |
| } |
| |
| /** |
| * Recursively sets the menu of all children of <code>composite</code>. |
| * |
| * @deprecated Use {@link CommonUiUtil#setMenu(Composite,Menu)} instead |
| */ |
| @Deprecated |
| public static void setMenu(Composite composite, Menu menu) { |
| CommonUiUtil.setMenu(composite, menu); |
| } |
| |
| /** |
| * @deprecated use {@link RowLayout#center} instead |
| */ |
| @Deprecated |
| public static void center(RowLayout rowLayout) { |
| try { |
| Field field = RowLayout.class.getDeclaredField("center"); //$NON-NLS-1$ |
| field.set(rowLayout, Boolean.TRUE); |
| } catch (Throwable e) { |
| // ignore |
| } |
| } |
| |
| public static Composite createBorder(Composite composite, final FormToolkit toolkit, boolean paintBorder) { |
| // create composite to hold rounded border |
| final Composite roundedBorder = toolkit.createComposite(composite); |
| if (paintBorder) { |
| roundedBorder.addPaintListener(new PaintListener() { |
| public void paintControl(PaintEvent e) { |
| e.gc.setForeground(toolkit.getColors().getBorderColor()); |
| Point size = roundedBorder.getSize(); |
| e.gc.drawRoundRectangle(0, 2, size.x - 1, size.y - 5, 5, 5); |
| } |
| }); |
| roundedBorder.setLayout(GridLayoutFactory.fillDefaults().margins(4, 6).create()); |
| } else { |
| roundedBorder.setLayout(GridLayoutFactory.fillDefaults().margins(0, 6).create()); |
| } |
| GridDataFactory.fillDefaults() |
| .align(SWT.FILL, SWT.BEGINNING) |
| .hint(EditorUtil.MAXIMUM_WIDTH, SWT.DEFAULT) |
| .grab(true, false) |
| .applyTo(roundedBorder); |
| return roundedBorder; |
| } |
| |
| public static Composite createBorder(Composite composite, final FormToolkit toolkit) { |
| return createBorder(composite, toolkit, true); |
| } |
| |
| public static Font setHeaderFontSizeAndStyle(Control text) { |
| GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).grab(true, false).applyTo(text); |
| // .hint(EditorUtil.MAXIMUM_WIDTH, SWT.DEFAULT) |
| |
| float sizeFactor = 1.1f; |
| Font initialFont = text.getFont(); |
| FontData[] fontData = initialFont.getFontData(); |
| for (FontData element : fontData) { |
| element.setHeight((int) (element.getHeight() * sizeFactor)); |
| element.setStyle(element.getStyle() | SWT.BOLD); |
| } |
| final Font textFont = new Font(text.getDisplay(), fontData); |
| text.setFont(textFont); |
| text.addDisposeListener(new DisposeListener() { |
| public void widgetDisposed(DisposeEvent e) { |
| textFont.dispose(); |
| } |
| }); |
| Color color = PlatformUI.getWorkbench() |
| .getThemeManager() |
| .getCurrentTheme() |
| .getColorRegistry() |
| .get(CommonThemes.COLOR_COMPLETED); |
| text.setForeground(color); |
| return textFont; |
| } |
| |
| public static GridData getTextControlLayoutData(TaskFormPage page, Control control, boolean expandVertically) { |
| final GridData gd = new GridData(); |
| // wrap text at this margin, see comment below |
| int width = getEditorWidth(page); |
| // the goal is to make the text viewer as big as the text so it does not require scrolling when first drawn |
| // on screen |
| Point size = control.computeSize(width, SWT.DEFAULT, true); |
| gd.widthHint = EditorUtil.MAXIMUM_WIDTH; |
| gd.minimumWidth = EditorUtil.MAXIMUM_WIDTH; |
| gd.horizontalAlignment = SWT.FILL; |
| gd.grabExcessHorizontalSpace = true; |
| // limit height to be avoid dynamic resizing of the text widget: |
| // MAXIMUM_HEIGHT < height < MAXIMUM_HEIGHT * 3 |
| //gd.minimumHeight = AbstractAttributeEditor.MAXIMUM_HEIGHT; |
| gd.heightHint = Math.min(Math.max(EditorUtil.MAXIMUM_HEIGHT, size.y), EditorUtil.MAXIMUM_HEIGHT * 3); |
| if (expandVertically) { |
| gd.verticalAlignment = SWT.FILL; |
| gd.grabExcessVerticalSpace = true; |
| } |
| return gd; |
| // shrink the text control if the editor width is reduced, otherwise the text field will always keep it's original |
| // width and will cause the editor to have a horizonal scroll bar |
| // composite.addControlListener(new ControlAdapter() { |
| // @Override |
| // public void controlResized(ControlEvent e) { |
| // int width = sectionComposite.getSize().x; |
| // Point size = descriptionTextViewer.getTextWidget().computeSize(width, SWT.DEFAULT, true); |
| // // limit width to parent widget |
| // gd.widthHint = width; |
| // // limit height to avoid dynamic resizing of the text widget |
| // gd.heightHint = Math.min(Math.max(DESCRIPTION_HEIGHT, size.y), DESCRIPTION_HEIGHT * 4); |
| // sectionComposite.layout(); |
| // } |
| // }); |
| |
| } |
| |
| private static int getEditorWidth(TaskFormPage page) { |
| int widthHint = 0; |
| if (page.getManagedForm() != null && page.getManagedForm().getForm() != null) { |
| widthHint = page.getManagedForm().getForm().getClientArea().width - 90; |
| } |
| if (widthHint <= 0 && page.getEditor().getEditorSite() != null |
| && page.getEditor().getEditorSite().getPage() != null) { |
| // EditorAreaHelper editorManager = ((WorkbenchPage) page.getEditor().getEditorSite().getPage()).getEditorPresentation(); |
| // if (editorManager != null && editorManager.getLayoutPart() != null) { |
| // widthHint = editorManager.getLayoutPart().getControl().getBounds().width - 90; |
| // } |
| // XXX e4.0 this does not work, the composite is always null |
| Composite composite = ((WorkbenchPage) page.getEditor().getEditorSite().getPage()).getClientComposite(); |
| if (composite != null) { |
| widthHint = composite.getBounds().width - 90; |
| } |
| } |
| if (widthHint <= 0) { |
| widthHint = EditorUtil.MAXIMUM_WIDTH; |
| } |
| return widthHint; |
| } |
| |
| public static GridLayout createSectionClientLayout() { |
| GridLayout layout = new GridLayout(); |
| layout.marginHeight = 0; |
| // leave 1px for borders |
| layout.marginTop = 2; |
| // spacing if a section is expanded |
| layout.marginBottom = 8; |
| return layout; |
| } |
| |
| public static void initializeScrollbars(ScrolledForm form) { |
| // initialize scroll bars |
| ScrollBar hbar = form.getHorizontalBar(); |
| if (hbar != null) { |
| hbar.setIncrement(PAGE_H_SCROLL_INCREMENT); |
| } |
| } |
| |
| public static String removeColon(String label) { |
| label = label.trim(); |
| return (label.endsWith(":")) ? label.substring(0, label.length() - 1) : label; //$NON-NLS-1$ |
| } |
| |
| public static void scroll(ScrolledComposite scomp, int xoffset, int yoffset) { |
| Point origin = scomp.getOrigin(); |
| Point contentSize = scomp.getContent().getSize(); |
| int xorigin = origin.x + xoffset; |
| int yorigin = origin.y + yoffset; |
| xorigin = Math.max(xorigin, 0); |
| xorigin = Math.min(xorigin, contentSize.x - 1); |
| yorigin = Math.max(yorigin, 0); |
| yorigin = Math.min(yorigin, contentSize.y - 1); |
| scomp.setOrigin(xorigin, yorigin); |
| } |
| |
| public static void addScrollListener(final Scrollable textWidget) { |
| textWidget.addMouseWheelListener(new MouseWheelListener() { |
| public void mouseScrolled(MouseEvent event) { |
| ScrolledComposite form = FormUtil.getScrolledComposite(textWidget); |
| if (form != null) { |
| ScrollBar verticalBar = textWidget.getVerticalBar(); |
| if (event.count < 0) { |
| // scroll form down |
| if (verticalBar == null |
| || verticalBar.getSelection() + verticalBar.getThumb() == verticalBar.getMaximum()) { |
| EditorUtil.scroll(form, 0, form.getVerticalBar().getIncrement()); |
| } |
| } else { |
| // scroll form up |
| if (verticalBar == null || verticalBar.getSelection() == verticalBar.getMinimum()) { |
| EditorUtil.scroll(form, 0, -form.getVerticalBar().getIncrement()); |
| } |
| } |
| } |
| } |
| }); |
| } |
| |
| public static void addScrollListener(final CCombo combo) { |
| if (PlatformUiUtil.usesMouseWheelEventsForScrolling()) { |
| combo.addListener(SWT.MouseWheel, new Listener() { |
| public void handleEvent(Event event) { |
| if (event.count > 0) { |
| EditorUtil.handleScrollUp(combo, event); |
| } else if (event.count < 0) { |
| EditorUtil.handleScrollDown(combo, event); |
| } |
| } |
| |
| }); |
| } else { |
| combo.addListener(SWT.KeyDown, new Listener() { |
| public void handleEvent(Event event) { |
| if (event.keyCode == SWT.ARROW_UP) { |
| EditorUtil.handleScrollUp(combo, event); |
| } else if (event.keyCode == SWT.ARROW_DOWN) { |
| EditorUtil.handleScrollDown(combo, event); |
| } |
| } |
| }); |
| } |
| } |
| |
| private static void handleScrollUp(CCombo combo, Event event) { |
| if (combo.isFocusControl()) { |
| // could be a legitimate key event, let CCombo handle it |
| return; |
| } |
| ScrolledComposite form = FormUtil.getScrolledComposite(combo); |
| if (form != null) { |
| EditorUtil.scroll(form, 0, -form.getVerticalBar().getIncrement()); |
| event.doit = false; |
| } |
| } |
| |
| private static void handleScrollDown(CCombo combo, Event event) { |
| if (combo.isFocusControl()) { |
| // could be a legitimate key event, let CCombo handle it |
| return; |
| } |
| ScrolledComposite form = FormUtil.getScrolledComposite(combo); |
| if (form != null) { |
| EditorUtil.scroll(form, 0, form.getVerticalBar().getIncrement()); |
| event.doit = false; |
| } |
| } |
| |
| public static void setTitleBarForeground(ExpandableComposite composite, Color color) { |
| try { |
| Field field = ExpandableComposite.class.getDeclaredField("titleBarForeground"); //$NON-NLS-1$ |
| field.setAccessible(true); |
| field.set(composite, color); |
| } catch (Exception e) { |
| composite.setTitleBarForeground(color); |
| } |
| } |
| |
| } |