diff options
Diffstat (limited to 'target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf')
13 files changed, 3069 insertions, 0 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/jface/dialogs/CustomTitleAreaDialog.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/jface/dialogs/CustomTitleAreaDialog.java new file mode 100644 index 000000000..009c69b5e --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/jface/dialogs/CustomTitleAreaDialog.java @@ -0,0 +1,374 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.jface.dialogs; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.dialogs.TitleAreaDialog; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tcf.te.ui.swt.activator.UIPlugin; +import org.eclipse.ui.PlatformUI; + +/** + * Custom title area dialog implementation. + */ +public class CustomTitleAreaDialog extends TitleAreaDialog implements IMessageProvider { + protected static final int comboHistoryLength = 10; + private String contextHelpId = null; + + // The dialog settings storage + private IDialogSettings dialogSettings; + + private String message; + private int messageType; + private String errorMessage; + private String title; + + // The default message is shown to the user if no other message is set + private String defaultMessage; + private int defaultMessageType; + + /** + * Constructor. + * + * @param parent The parent shell used to view the dialog. + */ + public CustomTitleAreaDialog(Shell parent) { + this(parent, null); + } + + /** + * Constructor. + * + * @param parent The parent shell used to view the dialog, or <code>null</code>. + * @param contextHelpId The dialog context help id or <code>null</code>. + */ + public CustomTitleAreaDialog(Shell parent, String contextHelpId) { + super(parent); + initializeDialogSettings(); + setContextHelpId(contextHelpId); + } + + protected void setContextHelpId(String contextHelpId) { + this.contextHelpId = contextHelpId; + setHelpAvailable(contextHelpId != null); + } + + /** + * Initialize the dialog settings storage. + */ + protected void initializeDialogSettings() { + IDialogSettings settings = doGetDialogSettingsToInitialize(); + Assert.isNotNull(settings); + IDialogSettings section = settings.getSection(getDialogSettingsSectionName()); + if (section == null) { + section = settings.addNewSection(getDialogSettingsSectionName()); + } + setDialogSettings(section); + } + + /** + * Returns the dialog settings container to use and to initialize. This + * method is called from <code>initializeDialogSettings</code> and allows + * overriding the dialog settings container without changing the dialog + * settings structure. + * + * @return The dialog settings container to use. Must not be <code>null</code>. + */ + protected IDialogSettings doGetDialogSettingsToInitialize() { + return UIPlugin.getDefault().getDialogSettings(); + } + + /** + * Returns the section name to use for separating different persistent + * dialog settings from different dialogs. + * + * @return The section name used to store the persistent dialog settings within the plugins persistent + * dialog settings store. + */ + public String getDialogSettingsSectionName() { + return "CustomTitleAreaDialog"; //$NON-NLS-1$ + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#create() + */ + @Override + public void create() { + super.create(); + + // If the dialog got set a message, make sure the message is really shown + // to the user from the beginning. + if (isMessageSet()) { + if (errorMessage != null) { + super.setErrorMessage(errorMessage); + } + else { + super.setMessage(message, messageType); + } + } else if (defaultMessage != null) { + // Default message set + super.setMessage(defaultMessage, defaultMessageType); + } + + // If the dialog got set a title, make sure the title is shown + if (title != null) { + super.setTitle(title); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite) + */ + @Override + protected Control createDialogArea(Composite parent) { + if (contextHelpId != null) { + PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, contextHelpId); + } + + // Let the super implementation create the dialog area control + Control control = super.createDialogArea(parent); + // But fix the layout data for the top control + if (control instanceof Composite) { + configureDialogAreaControl((Composite)control); + } + + return control; + } + + /** + * Configure the dialog top control. + * + * @param composite The dialog top control. Must not be <code>null</code>. + */ + protected void configureDialogAreaControl(Composite composite) { + Assert.isNotNull(composite); + Layout layout = composite.getLayout(); + if (layout == null || layout instanceof GridLayout) { + composite.setLayout(new GridLayout()); + } + } + + /** + * Returns the associated dialog settings storage. + * + * @return The dialog settings storage. + */ + public IDialogSettings getDialogSettings() { + // The dialog settings may not been initialized here. Initialize first in this case + // to be sure that we do have always the correct dialog settings. + if (dialogSettings == null) { + initializeDialogSettings(); + } + return dialogSettings; + } + + /** + * Sets the associated dialog settings storage. + * + * @return The dialog settings storage. + */ + public void setDialogSettings(IDialogSettings dialogSettings) { + this.dialogSettings = dialogSettings; + } + + /** + * Adds the given string to the given string array. + * + * @param history String array to add the given entry to it. + * @param newEntry The new entry to add. + * @return The updated string array containing the old array content plus the new entry. + */ + protected String[] addToHistory(String[] history, String newEntry) { + List<String> l = new ArrayList<String>(Arrays.asList(history)); + addToHistory(l, newEntry); + String[] r = new String[l.size()]; + l.toArray(r); + return r; + } + + /** + * Adds the given string to the given list. + * + * @param history List to add the given entry to it. + * @param newEntry The new entry to add. Must not be <code>null</code> + * + * @return The updated list containing the old list content plus the new entry. + */ + protected void addToHistory(List<String> history, String newEntry) { + Assert.isNotNull(newEntry); + + history.remove(newEntry); + history.add(0, newEntry); + // since only one new item was added, we can be over the limit + // by at most one item + if (history.size() > comboHistoryLength) { + history.remove(comboHistoryLength); + } + } + + /** + * Save current dialog widgets values. + * Called by <code>okPressed</code>. + */ + protected void saveWidgetValues() { + return; + } + + /** + * Restore previous dialog widgets values. + * Note: This method is not called automatically! You have + * to call this method at the appropriate time and place. + */ + protected void restoreWidgetValues() { + return; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#okPressed() + */ + @Override + protected void okPressed() { + saveWidgetValues(); + super.okPressed(); + } + + /** + * Cleanup when dialog is closed. + */ + protected void dispose() { + dialogSettings = null; + message = null; + messageType = IMessageProvider.NONE; + errorMessage = null; + title = null; + defaultMessage = null; + defaultMessageType = IMessageProvider.NONE; + } + + /** + * Cleanup the Dialog and close it. + */ + @Override + public boolean close() { + dispose(); + return super.close(); + } + + /** + * Set the enabled state of the dialog button specified by the given id (@see <code>IDialogConstants</code>) + * to the given state. + * + * @param buttonId The button id for the button to change the enabled state for. + * @param enabled The new enabled state to set for the button. + */ + public void setButtonEnabled(int buttonId, boolean enabled) { + Button button = getButton(buttonId); + if (button != null) { + button.setEnabled(enabled); + } + } + + /** + * Sets the title for this dialog. + * + * @param title The title. + */ + public void setDialogTitle(String title) { + if (getShell() != null && !getShell().isDisposed()) { + getShell().setText(title); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.TitleAreaDialog#setTitle(java.lang.String) + */ + @Override + public void setTitle(String newTitle) { + title = newTitle; + super.setTitle(newTitle); + } + + /** + * Set the default message. The default message is shown within the + * dialogs message area if no other message is set. + * + * @param message The default message or <code>null</code>. + * @param type The default message type. See {@link IMessageProvider}. + */ + public void setDefaultMessage(String message, int type) { + defaultMessage = message; + defaultMessageType = type; + // Push the default message to the dialog if no other message is set + if (!isMessageSet() && getContents() != null) { + super.setMessage(defaultMessage, defaultMessageType); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.TitleAreaDialog#setMessage(java.lang.String, int) + */ + @Override + public void setMessage(String newMessage, int newType) { + // To be able to implement IMessageProvider, we have to remember the + // set message ourselfs. There is no access to these information by the + // base class. + message = newMessage; messageType = newType; + // Only pass on to super implementation if the control has been created yet + if (getContents() != null) { + super.setMessage(message != null ? message : defaultMessage, message != null ? messageType : defaultMessageType); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.TitleAreaDialog#setErrorMessage(java.lang.String) + */ + @Override + public void setErrorMessage(String newErrorMessage) { + // See setMessage(...) + errorMessage = newErrorMessage; + super.setErrorMessage(newErrorMessage); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.IMessageProvider#getMessage() + */ + @Override + public String getMessage() { + return errorMessage != null ? errorMessage : message; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.IMessageProvider#getMessageType() + */ + @Override + public int getMessageType() { + return errorMessage != null ? IMessageProvider.ERROR : messageType; + } + + /** + * Returns if or if not an message is set to the dialog. + * + * @return <code>True</code> if a message has been set, <code>false</code> otherwise. + */ + public boolean isMessageSet() { + return errorMessage != null || message != null; + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/jface/dialogs/CustomTrayDialog.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/jface/dialogs/CustomTrayDialog.java new file mode 100644 index 000000000..38e647197 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/jface/dialogs/CustomTrayDialog.java @@ -0,0 +1,247 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.jface.dialogs; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.dialogs.TrayDialog; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tcf.te.ui.swt.activator.UIPlugin; +import org.eclipse.ui.PlatformUI; + + +/** + * Custom tray dialog implementation. + */ +public class CustomTrayDialog extends TrayDialog { + protected static final int comboHistoryLength = 10; + private String contextHelpId = null; + + // the dialog storage + private IDialogSettings dialogSettings; + + /** + * Constructor. + * + * @param shell The parent shell or <code>null</code>. + */ + public CustomTrayDialog(Shell shell) { + this(shell, null); + } + + /** + * Constructor. + * + * @param shell The parent shell or <code>null</code>. + * @param contextHelpId The dialog context help id or <code>null</code>. + */ + public CustomTrayDialog(Shell shell, String contextHelpId) { + super(shell); + initializeDialogSettings(); + setContextHelpId(contextHelpId); + } + + /** + * Configure the dialogs context help id. + * + * @param contextHelpId The context help id or <code>null</code>. + */ + protected void setContextHelpId(String contextHelpId) { + this.contextHelpId = contextHelpId; + setHelpAvailable(contextHelpId != null); + } + + /** + * Initialize the dialog settings storage. + */ + protected void initializeDialogSettings() { + IDialogSettings settings = doGetDialogSettingsToInitialize(); + Assert.isNotNull(settings); + IDialogSettings section = settings.getSection(getDialogSettingsSectionName()); + if (section == null) { + section = settings.addNewSection(getDialogSettingsSectionName()); + } + setDialogSettings(section); + } + + /** + * Returns the dialog settings container to use and to initialize. This + * method is called from <code>initializeDialogSettings</code> and allows + * overriding the dialog settings container without changing the dialog + * settings structure. + * + * @return The dialog settings container to use. Must not be <code>null</code>. + */ + protected IDialogSettings doGetDialogSettingsToInitialize() { + return UIPlugin.getDefault().getDialogSettings(); + } + + /** + * Returns the section name to use for separating different persistent + * dialog settings from different dialogs. + * + * @return The section name used to store the persistent dialog settings within the plugins persistent + * dialog settings store. + */ + public String getDialogSettingsSectionName() { + return "CustomTrayDialog"; //$NON-NLS-1$ + } + + /** + * Returns the associated dialog settings storage. + * + * @return The dialog settings storage. + */ + public IDialogSettings getDialogSettings() { + // The dialog settings may not been initialized here. Initialize first in this case + // to be sure that we do have always the correct dialog settings. + if (dialogSettings == null) { + initializeDialogSettings(); + } + return dialogSettings; + } + + /** + * Sets the associated dialog settings storage. + * + * @return The dialog settings storage. + */ + public void setDialogSettings(IDialogSettings dialogSettings) { + this.dialogSettings = dialogSettings; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite) + */ + @Override + protected Control createDialogArea(Composite parent) { + if (contextHelpId != null) { + PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, contextHelpId); + } + + // Let the super implementation create the dialog area control + Control control = super.createDialogArea(parent); + // But fix the layout data for the top control + if (control instanceof Composite) { + configureDialogAreaControl((Composite)control); + } + + return control; + } + + /** + * Configure the dialog top control. + * + * @param composite The dialog top control. Must not be <code>null</code>. + */ + protected void configureDialogAreaControl(Composite composite) { + Assert.isNotNull(composite); + Layout layout = composite.getLayout(); + if (layout == null || layout instanceof GridLayout) { + composite.setLayout(new GridLayout()); + } + } + + /** + * Adds the given string to the given string array. + * + * @param history String array to add the given entry to it. + * @param newEntry The new entry to add. + * @return The updated string array containing the old array content plus the new entry. + */ + protected String[] addToHistory(String[] history, String newEntry) { + List<String> l = new ArrayList<String>(Arrays.asList(history)); + addToHistory(l, newEntry); + String[] r = new String[l.size()]; + l.toArray(r); + return r; + } + + /** + * Adds the given string to the given list. + * + * @param history List to add the given entry to it. + * @param newEntry The new entry to add. Must not be <code>null</code> + * + * @return The updated list containing the old list content plus the new entry. + */ + protected void addToHistory(List<String> history, String newEntry) { + Assert.isNotNull(newEntry); + + history.remove(newEntry); + history.add(0, newEntry); + // since only one new item was added, we can be over the limit + // by at most one item + if (history.size() > comboHistoryLength) { + history.remove(comboHistoryLength); + } + } + + /** + * Save current dialog widgets values. + * Called by <code>okPressed</code>. + */ + protected void saveWidgetValues() { + return; + } + + /** + * Restore previous dialog widgets values. + * Note: This method is not called automatically! You have + * to call this method at the appropriate time and place. + */ + protected void restoreWidgetValues() { + return; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#okPressed() + */ + @Override + protected void okPressed() { + saveWidgetValues(); + super.okPressed(); + } + + /** + * Cleanup when dialog is closed. + */ + protected void dispose() { + dialogSettings = null; + } + + /** + * Cleanup the Dialog and close it. + */ + @Override + public boolean close() { + dispose(); + return super.close(); + } + + /** + * Sets the title for this dialog. + * + * @param title The title. + */ + public void setDialogTitle(String title) { + if (getShell() != null && !getShell().isDisposed()) { + getShell().setText(title); + } + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/jface/dialogs/OptionalMessageDialog.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/jface/dialogs/OptionalMessageDialog.java new file mode 100644 index 000000000..ee98c6cd8 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/jface/dialogs/OptionalMessageDialog.java @@ -0,0 +1,674 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.jface.dialogs; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.dialogs.MessageDialogWithToggle; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Link; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; +import org.eclipse.tcf.te.ui.swt.activator.UIPlugin; +import org.eclipse.tcf.te.ui.swt.nls.Messages; +import org.eclipse.ui.PlatformUI; + +/** + * Message dialog with "do not show again" and optional help button. The Dialog + * stores the selected button result automatically, when "do not show again" was + * selected. All stored values can be cleared in the Target Explorer preferences + * root page. + * <p> + * Additional information (e.g. last opening time stamp for license warning) can + * be stored using <code>set/getAdditionalDialogInfo()</code>, that should + * also be cleared with the states. + */ +public class OptionalMessageDialog extends MessageDialogWithToggle { + + // section name for the dialog settings stored by this dialog + private static final String DIALOG_ID = "OptionalMessageDialog"; //$NON-NLS-1$ + + // context help id for the dialog + private String contextHelpId; + // the key where the result is stored within the dialog settings section + private String key; + + /** + * Constructor. Message dialog with "do not show again" and optional help + * button. The dialog automatically stores the pressed button when "do not + * show again" was selected. The next time the dialogs <code>open()</code> + * method is called it returns the stored value without opening the dialog. + * When the cancel button was pressed, _NO_ value will be stored. + * + * @param parentShell + * The shell. + * @param title + * The title for the message dialog. + * @param image + * The window icon or <code>null</code> if default icon should + * be used. + * @param message + * The dialog message text. + * @param imageType + * The dialog image type (QUESTION, INFORMATION, WARNING, ERROR). + * @param buttonLabels + * The labels for buttons. + * @param defaultIndex + * The default button index. + * @param key + * The unique key for the stored result value (e.g. "<PluginName>.<ActionOrDialogName>"). + * @param contextHelpId + * The optional help context id. If <code>null</code>, no help + * button will be shown. + */ + public OptionalMessageDialog(Shell parentShell, String title, Image image, String message, int imageType, String[] buttonLabels, int defaultIndex, String key, String contextHelpId) { + + super(parentShell, + title, + image, + message, + imageType, + buttonLabels != null ? buttonLabels : new String [] { IDialogConstants.OK_LABEL }, + defaultIndex, + Messages.getString(DIALOG_ID + (imageType == QUESTION ? "_rememberMyDecision_label" : "_doNotShowAgain_label")), //$NON-NLS-1$ //$NON-NLS-2$ + false); + + this.contextHelpId = contextHelpId; + this.key = key == null || key.trim().length() == 0 ? null : key.trim(); + + if (contextHelpId != null) { + PlatformUI.getWorkbench().getHelpSystem().setHelp(parentShell, contextHelpId); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#isResizable() + */ + @Override + protected boolean isResizable() { + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.IconAndMessageDialog#createButtonBar(org.eclipse.swt.widgets.Composite) + */ + @Override + protected Control createButtonBar(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(2, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.horizontalSpacing = 0; + composite.setLayout(layout); + GridData gd = new GridData(SWT.FILL, SWT.BOTTOM, true, false); + if (parent.getLayout() instanceof GridLayout) { + gd.horizontalSpan = ((GridLayout)parent.getLayout()).numColumns; + } + composite.setLayoutData(gd); + composite.setFont(parent.getFont()); + + // create help control if needed + if (contextHelpId != null) { + Control helpControl = createHelpControl(composite); + ((GridData)helpControl.getLayoutData()).horizontalIndent = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN); + } + + Control buttonSection = super.createButtonBar(composite); + ((GridData)buttonSection.getLayoutData()).grabExcessHorizontalSpace = true; + return composite; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.MessageDialog#createButton(org.eclipse.swt.widgets.Composite, int, java.lang.String, boolean) + */ + @Override + protected Button createButton(Composite parent, int id, String label, boolean defaultButton) { + // Allow to re-adjust the button id's. Base implementation is matching + // the button labels against the well known labels defined by IDialogConstants. + // For labels not defined there, the implementation set id's starting with 256. + return super.createButton(parent, adjustButtonIdForLabel(id, label), label, defaultButton); + } + + /** + * Adjust the button id to use for the button with the given label. + * <p> + * <b>Note:</b>Base implementation is matching the button labels against the well known + * labels defined by {@link IDialogConstants}. For labels not defined there, the implementation + * set id's starting with 256. + * <p> + * The default implementation returns the button id unmodified. + * + * @param id The suggested button id. + * @param label The button label. + * @return The effective button id. + */ + protected int adjustButtonIdForLabel(int id, String label) { + return id; + } + + private Control createHelpControl(Composite parent) { + Image helpImage = JFaceResources.getImage(DLG_IMG_HELP); + if (helpImage != null) { + return createHelpImageButton(parent, helpImage); + } + return createHelpLink(parent); + } + + /* + * Creates a button with a help image. This is only used if there + * is an image available. + */ + private ToolBar createHelpImageButton(Composite parent, Image image) { + ToolBar toolBar = new ToolBar(parent, SWT.FLAT | SWT.NO_FOCUS); + ((GridLayout)parent.getLayout()).numColumns++; + toolBar.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER)); + final Cursor cursor = new Cursor(parent.getDisplay(), SWT.CURSOR_HAND); + toolBar.setCursor(cursor); + toolBar.addDisposeListener(new DisposeListener() { + @Override + public void widgetDisposed(DisposeEvent e) { + cursor.dispose(); + } + }); + ToolItem item = new ToolItem(toolBar, SWT.NONE); + item.setImage(image); + item.setToolTipText(JFaceResources.getString("helpToolTip")); //$NON-NLS-1$ + item.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + helpPressed(); + } + }); + return toolBar; + } + + /* + * Creates a help link. This is used when there is no help image + * available. + */ + private Link createHelpLink(Composite parent) { + Link link = new Link(parent, SWT.WRAP | SWT.NO_FOCUS); + ((GridLayout)parent.getLayout()).numColumns++; + link.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER)); + link.setText("<a>" + IDialogConstants.HELP_LABEL + "</a>"); //$NON-NLS-1$ //$NON-NLS-2$ + link.setToolTipText(IDialogConstants.HELP_LABEL); + link.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + helpPressed(); + } + }); + return link; + } + + /** + * Invoked if the help button is pressed. + */ + /* default */ void helpPressed() { + if (getShell() != null) { + Control c = getShell().getDisplay().getFocusControl(); + while (c != null) { + if (c.isListening(SWT.Help)) { + c.notifyListeners(SWT.Help, new Event()); + break; + } + c = c.getParent(); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.MessageDialog#createCustomArea(org.eclipse.swt.widgets.Composite) + */ + @Override + protected Control createCustomArea(Composite parent) { + if (contextHelpId != null) { + PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, contextHelpId); + } + Label label = new Label(parent, SWT.NULL); + label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + return label; + } + + /** + * Opens the dialog only, if no dialog result is stored and this dialog + * should be displayed. If a dialog result is stored, this state will be + * returned without opening the dialog. When the dialog is closed and "do + * not show again" was selected, the result will be stored. + * + * @see org.eclipse.jface.window.Window#open() + */ + @Override + public int open() { + int result = getDialogResult(key); + if (result < 0) { + result = super.open(); + if (getToggleState() && result >= 0 && result != IDialogConstants.CANCEL_ID) { + setDialogResult(key, result); + } + } + return result; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.MessageDialogWithToggle#setToggleButton(org.eclipse.swt.widgets.Button) + */ + @Override + protected void setToggleButton(Button button) { + // if no key is given, no toggle button should be displayed + if (button != null && key != null) { + super.setToggleButton(button); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.MessageDialogWithToggle#createToggleButton(org.eclipse.swt.widgets.Composite) + */ + @Override + protected Button createToggleButton(Composite parent) { + // if no key is given, no toggle button should be created + if (key != null) { + return super.createToggleButton(parent); + } + return null; + } + /** + * Opens a question dialog with OK and CANCEL. + * + * @param parentShell + * The shell. + * @param title + * The title for the message dialog. + * @param message + * The dialog message text. + * @param key + * The unique key for the stored result value (e.g. "<PluginName>.<ActionOrDialogName>"). + * @param contextHelpId + * The optional help context id. If <code>null</code>, no help + * button will be shown. + * @return The stored or selected result. + */ + public static int openOkCancelDialog(Shell parentShell, String title, String message, String key, String contextHelpId) { + return openOkCancelDialog(parentShell, title, message, null, key, contextHelpId); + } + + /** + * Opens a question dialog with OK and CANCEL. + * + * @param parentShell + * The shell. + * @param title + * The title for the message dialog. + * @param message + * The dialog message text. + * @param buttonLabel + * An string array listing the labels of the message dialog buttons. If <code>null</code>, the default + * labeling, typically "OK" for a single button message dialog, will be applied. + * @param key + * The unique key for the stored result value (e.g. "<PluginName>.<ActionOrDialogName>"). + * @param contextHelpId + * The optional help context id. If <code>null</code>, no help + * button will be shown. + * @return The stored or selected result. + */ + public static int openOkCancelDialog(Shell parentShell, String title, String message, String[] buttonLabel, String key, String contextHelpId) { + if (buttonLabel == null) buttonLabel = new String[] { IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL }; + OptionalMessageDialog dialog = new OptionalMessageDialog(parentShell, title, null, message, QUESTION, buttonLabel, 0, key, contextHelpId); + return dialog.open(); + } + + /** + * Opens a question dialog with YES, NO and CANCEL. + * + * @param parentShell + * The shell. + * @param title + * The title for the message dialog. + * @param message + * The dialog message text. + * @param key + * The unique key for the stored result value (e.g. "<PluginName>.<ActionOrDialogName>"). + * @param contextHelpId + * The optional help context id. If <code>null</code>, no help + * button will be shown. + * @return The stored or selected result. + */ + public static int openYesNoCancelDialog(Shell parentShell, String title, String message, String key, String contextHelpId) { + return openYesNoCancelDialog(parentShell, title, message, null, key, contextHelpId); + } + + /** + * Opens a question dialog with YES, NO and CANCEL. + * + * @param parentShell + * The shell. + * @param title + * The title for the message dialog. + * @param message + * The dialog message text. + * @param buttonLabel + * An string array listing the labels of the message dialog buttons. If <code>null</code>, the default + * labeling, typically "OK" for a single button message dialog, will be applied. + * @param key + * The unique key for the stored result value (e.g. "<PluginName>.<ActionOrDialogName>"). + * @param contextHelpId + * The optional help context id. If <code>null</code>, no help + * button will be shown. + * @return The stored or selected result. + */ + public static int openYesNoCancelDialog(Shell parentShell, String title, String message, String[] buttonLabel, String key, String contextHelpId) { + if (buttonLabel == null) buttonLabel = new String[] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL, IDialogConstants.CANCEL_LABEL }; + OptionalMessageDialog dialog = new OptionalMessageDialog(parentShell, title, null, message, QUESTION, buttonLabel, 0, key, contextHelpId); + return dialog.open(); + } + + /** + * Opens a question dialog with YES and NO. + * + * @param parentShell + * The shell. + * @param title + * The title for the message dialog. + * @param message + * The dialog message text. + * @param key + * The unique key for the stored result value (e.g. "<PluginName>.<ActionOrDialogName>"). + * @param contextHelpId + * The optional help context id. If <code>null</code>, no help + * button will be shown. + * @return The stored or selected result. + */ + public static int openYesNoDialog(Shell parentShell, String title, String message, String key, String contextHelpId) { + return openYesNoDialog(parentShell, title, message, null, key, contextHelpId); + } + + /** + * Opens a question dialog with YES and NO. + * + * @param parentShell + * The shell. + * @param title + * The title for the message dialog. + * @param message + * The dialog message text. + * @param buttonLabel + * An string array listing the labels of the message dialog buttons. If <code>null</code>, the default + * labeling, typically "OK" for a single button message dialog, will be applied. + * @param key + * The unique key for the stored result value (e.g. "<PluginName>.<ActionOrDialogName>"). + * @param contextHelpId + * The optional help context id. If <code>null</code>, no help + * button will be shown. + * @return The stored or selected result. + */ + public static int openYesNoDialog(Shell parentShell, String title, String message, String[] buttonLabel, String key, String contextHelpId) { + if (buttonLabel == null) buttonLabel = new String[] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL }; + OptionalMessageDialog dialog = new OptionalMessageDialog(parentShell, title, null, message, QUESTION, buttonLabel, 0, key, contextHelpId); + return dialog.open(); + } + + /** + * Opens a info dialog with OK. + * + * @param parentShell + * The shell. + * @param title + * The title for the message dialog. + * @param message + * The dialog message text. + * @param key + * The unique key for the stored result value (e.g. "<PluginName>.<ActionOrDialogName>"). + * @param contextHelpId + * The optional help context id. If <code>null</code>, no help + * button will be shown. + * @return The stored or selected result. + */ + public static int openInformationDialog(Shell parentShell, String title, String message, String key, String contextHelpId) { + return openInformationDialog(parentShell, title, message, null, key, contextHelpId); + } + + /** + * Opens a info dialog with OK. + * + * @param parentShell + * The shell. + * @param title + * The title for the message dialog. + * @param message + * The dialog message text. + * @param buttonLabel + * An string array listing the labels of the message dialog buttons. If <code>null</code>, the default + * labeling, typically "OK" for a single button message dialog, will be applied. + * @param key + * The unique key for the stored result value (e.g. "<PluginName>.<ActionOrDialogName>"). + * @param contextHelpId + * The optional help context id. If <code>null</code>, no help + * button will be shown. + * @return The stored or selected result. + */ + public static int openInformationDialog(Shell parentShell, String title, String message, String[] buttonLabel, String key, String contextHelpId) { + if (buttonLabel == null) buttonLabel = new String[] { IDialogConstants.OK_LABEL }; + OptionalMessageDialog dialog = new OptionalMessageDialog(parentShell, title, null, message, INFORMATION, buttonLabel, 0, key, contextHelpId); + return dialog.open(); + } + + /** + * Opens a warning dialog with OK. + * + * @param parentShell + * The shell. + * @param title + * The title for the message dialog. + * @param message + * The dialog message text. + * @param key + * The unique key for the stored result value (e.g. "<PluginName>.<ActionOrDialogName>"). + * @param contextHelpId + * The optional help context id. If <code>null</code>, no help + * button will be shown. + * @return The stored or selected result. + */ + public static int openWarningDialog(Shell parentShell, String title, String message, String key, String contextHelpId) { + return openWarningDialog(parentShell, title, message, null, key, contextHelpId); + } + + /** + * Opens a warning dialog with OK. + * + * @param parentShell + * The shell. + * @param title + * The title for the message dialog. + * @param message + * The dialog message text. + * @param buttonLabel + * An string array listing the labels of the message dialog buttons. If <code>null</code>, the default + * labeling, typically "OK" for a single button message dialog, will be applied. + * @param key + * The unique key for the stored result value (e.g. "<PluginName>.<ActionOrDialogName>"). + * @param contextHelpId + * The optional help context id. If <code>null</code>, no help + * button will be shown. + * @return The stored or selected result. + */ + public static int openWarningDialog(Shell parentShell, String title, String message, String[] buttonLabel, String key, String contextHelpId) { + if (buttonLabel == null) buttonLabel = new String[] { IDialogConstants.OK_LABEL }; + OptionalMessageDialog dialog = new OptionalMessageDialog(parentShell, title, null, message, WARNING, buttonLabel, 0, key, contextHelpId); + return dialog.open(); + } + + /** + * Opens a error dialog with OK. + * + * @param parentShell + * The shell. + * @param title + * The title for the message dialog. + * @param message + * The dialog message text. + * @param key + * The unique key for the stored result value (e.g. "<PluginName>.<ActionOrDialogName>"). + * @param contextHelpId + * The optional help context id. If <code>null</code>, no help + * button will be shown. + * @return The stored or selected result. + */ + public static int openErrorDialog(Shell parentShell, String title, String message, String key, String contextHelpId) { + return openErrorDialog(parentShell, title, message, null, key, contextHelpId); + } + + /** + * Opens a error dialog with OK. + * + * @param parentShell + * The shell. + * @param title + * The title for the message dialog. + * @param message + * The dialog message text. + * @param buttonLabel + * An string array listing the labels of the message dialog buttons. If <code>null</code>, the default + * labeling, typically "OK" for a single button message dialog, will be applied. + * @param key + * The unique key for the stored result value (e.g. "<PluginName>.<ActionOrDialogName>"). + * @param contextHelpId + * The optional help context id. If <code>null</code>, no help + * button will be shown. + * @return The stored or selected result. + */ + public static int openErrorDialog(Shell parentShell, String title, String message, String[] buttonLabel, String key, String contextHelpId) { + if (buttonLabel == null) buttonLabel = new String[] { IDialogConstants.OK_LABEL }; + OptionalMessageDialog dialog = new OptionalMessageDialog(parentShell, title, null, message, ERROR, buttonLabel, 0, key, contextHelpId); + return dialog.open(); + } + + /* + * Get the dialog settings section or create it when it is not available. + */ + private static IDialogSettings getDialogSettings() { + IDialogSettings settings = UIPlugin.getDefault().getDialogSettings(); + settings = settings.getSection(DIALOG_ID); + if (settings == null) + settings = UIPlugin.getDefault().getDialogSettings().addNewSection(DIALOG_ID); + return settings; + } + + /** + * Get the stored result for this key. If the dialog should be opened, -1 + * will be returned. + * + * @param key + * The key for the stored result. + * @return The stored result or -1 of the dialog should be opened. + */ + public static int getDialogResult(String key) { + IDialogSettings settings = getDialogSettings(); + try { + return settings.getInt(key + ".result"); //$NON-NLS-1$ + } + catch (NumberFormatException e) { + } + return -1; + } + + /** + * Get the stored toggle state for this key. + * If no state is stored, <code>false</code> will be returned. + * + * @param key + * The key for the stored toggle state. + * @return The stored result or -1 of the dialog should be opened. + */ + public static boolean getDialogToggleState(String key) { + IDialogSettings settings = getDialogSettings(); + return settings.getBoolean(key + ".toggleState"); //$NON-NLS-1$ + } + + /** + * Get the stored info for this key. + * + * @param key + * The key for the stored info. + * @return The stored info or <code>null</code>. + */ + public static String getAdditionalDialogInfo(String key) { + IDialogSettings settings = getDialogSettings(); + return settings.get(key + ".additionalInfo"); //$NON-NLS-1$ + } + + /** + * Set the dialog result for this key. If the result is < 0, the string + * "PROMPT" will be stored. + * + * @param key + * The key to store the result. + * @param result + * The result that should be stored. + */ + public static void setDialogResult(String key, int result) { + IDialogSettings settings = getDialogSettings(); + if (result < 0) { + settings.put(key + ".result", PROMPT); //$NON-NLS-1$ + } + else { + settings.put(key + ".result", result); //$NON-NLS-1$ + } + } + + /** + * Set the dialog toggle state for this key. + * + * @param key + * The key to store the toggle state. + * @param result + * The toggle state that should be stored. + */ + public static void setDialogToggleState(String key, boolean state) { + IDialogSettings settings = getDialogSettings(); + settings.put(key + ".toggleState", state); //$NON-NLS-1$ + } + + /** + * Set additional info for this key. + * + * @param key + * The key to store the additional info. + * @param value + * The additional info that should be stored. + */ + public static void setAdditionalDialogInfo(String key, String value) { + IDialogSettings settings = getDialogSettings(); + settings.put(key + ".additionalInfo", value); //$NON-NLS-1$ + } + + /** + * Clears all stored information for this dialogs + */ + public static void clearAllRememberedStates() { + IDialogSettings settings = UIPlugin.getDefault().getDialogSettings(); + settings.addNewSection(DIALOG_ID); + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/jface/images/AbstractImageDescriptor.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/jface/images/AbstractImageDescriptor.java new file mode 100644 index 000000000..4d86a552b --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/jface/images/AbstractImageDescriptor.java @@ -0,0 +1,289 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.jface.images; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.resource.CompositeImageDescriptor; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.Point; + +/** + * Extended composite image descriptor. + * <p> + * The image descriptor implementation adds method for easily drawing overlay + * images on different positions on top of a base image. + */ +public abstract class AbstractImageDescriptor extends CompositeImageDescriptor { + // The parent image registry providing the images for drawing + private final ImageRegistry parentImageRegistry; + + // The image descriptor key + private String descriptorKey = null; + + /** + * Constructor. + * + * @param parent The parent image registry. Must not be <code>null</code>. + */ + public AbstractImageDescriptor(ImageRegistry parent) { + super(); + + Assert.isNotNull(parent); + parentImageRegistry = parent; + } + + /** + * Returns the parent image registry. + * + * @return The parent image registry instance. + */ + protected final ImageRegistry getParentImageRegistry() { + return parentImageRegistry; + } + + /** + * Set the image descriptor key. + * + * @param key The image descriptor key. Must not be <code>null</code>. + */ + protected final void setDecriptorKey(String key) { + Assert.isNotNull(key); + descriptorKey = key; + } + + /** + * Returns the image descriptor key. + * + * @return The image descriptor key, or <code>null</code> if not set. + */ + public final String getDecriptorKey() { + return descriptorKey; + } + + /** + * Draw the image, found under the specified key, centered within the + * rectangle given by width x height. + * + * @param key The image key. Must not be <code>null</code>. + * @param width The width of the rectangle to center the image in. + * @param height The height of the rectangle to center the image in. + */ + protected void drawCentered(String key, int width, int height) { + Assert.isNotNull(key); + drawCentered(parentImageRegistry.get(key), width, height); + } + + /** + * Draw the given image centered within the rectangle + * defined by the specified width x height. + * + * @param image The image. Must not be <code>null</code>. + * @param width The width of the rectangle to center the image in. + * @param height The height of the rectangle to center the image in. + */ + protected void drawCentered(Image image, int width, int height) { + if (image != null) { + ImageData imageData = image.getImageData(); + if (imageData != null) { + int x = StrictMath.max(0, (width - imageData.width + 1) / 2); + int y = StrictMath.max(0, (height - imageData.height + 1) / 2); + drawImage(imageData, x, y); + } + } + } + + /** + * Draw the overlay image, found under the specified key in the parent + * image registry, centered right on top of the base image. + * + * @param key The overlay image key. Must not be <code>null</code>. + * @param width The width of the base image. + * @param height The height of the base image. + */ + protected void drawCenterRight(String key, int width, int height) { + Image image = parentImageRegistry.get(key); + if (image != null) { + ImageData imageData = image.getImageData(); + if (imageData != null) { + int x = StrictMath.max(0, width - imageData.width); + int y = StrictMath.max(0, (height - imageData.height + 1) / 2); + drawImage(imageData, x, y); + } + } + } + + /** + * Draw the overlay image, found under the specified key in the parent + * image registry, top left on top of the base image. + * + * @param key The overlay image key. Must not be <code>null</code>. + */ + protected void drawTopLeft(String key) { + Image image = parentImageRegistry.get(key); + if (image != null) { + ImageData imageData = image.getImageData(); + if (imageData != null) { + drawImage(imageData, 0, 0); + } + } + } + + /** + * Draw the overlay image, found under the specified key in the parent + * image registry, top right on top of the base image. + * + * @param key The overlay image key. Must not be <code>null</code>. + */ + protected void drawTopRight(String key) { + if (getSize() != null) { + Point size = getSize(); + drawTopRight(key, size.x, size.y); + } else { + // the default eclipse style guide recommendation is 16x16 + drawTopRight(key, 16, 16); + } + } + + /** + * Draw the overlay image, found under the specified key in the parent + * image registry, top right on top of the base image. + * + * @param key The overlay image key. Must not be <code>null</code>. + * @param width The width of the base image. + * @param height The height of the base image. + */ + protected void drawTopRight(String key, int width, int height) { + Image image = parentImageRegistry.get(key); + if (image != null) { + ImageData imageData = image.getImageData(); + if (imageData != null) { + int x = StrictMath.max(0, width - imageData.width); + drawImage(imageData, x, 0); + } + } + } + + /** + * Draw the overlay image, found under the specified key in the parent + * image registry, bottom center on top of the base image. + * + * @param key The overlay image key. Must not be <code>null</code>. + * @param width The width of the base image. + * @param height The height of the base image. + */ + protected void drawBottomCenter(String key, int width, int height) { + Image image = parentImageRegistry.get(key); + if (image != null) { + ImageData imageData = image.getImageData(); + if (imageData != null) { + int x = StrictMath.max(0, (width - imageData.width + 1) / 2); + int y = StrictMath.max(0, height - imageData.height); + drawImage(imageData, x, y); + } + } + } + + /** + * Draw the overlay image, found under the specified key in the parent + * image registry, bottom left on top of the base image. + * + * @param key The overlay image key. Must not be <code>null</code>. + * @param width The width of the base image. + * @param height The height of the base image. + */ + protected void drawBottomLeft(String key, int width, int height) { + Image image = parentImageRegistry.get(key); + if (image != null) { + ImageData imageData = image.getImageData(); + if (imageData != null) { + int y = StrictMath.max(0, height - imageData.height); + drawImage(imageData, 0, y); + } + } + } + + /** + * Draw the overlay image, found under the specified key in the parent + * image registry, center left on top of the base image. + * + * @param key The overlay image key. Must not be <code>null</code>. + * @param width The width of the base image. + * @param height The height of the base image. + */ + protected void drawCenterLeft(String key, int width, int height) { + Image image = parentImageRegistry.get(key); + if (image != null) { + ImageData imageData = image.getImageData(); + if (imageData != null) { + int y = StrictMath.max(0, (height - imageData.height) / 2); + drawImage(imageData, 0, y); + } + } + } + + /** + * Draw the overlay image, found under the specified key in the parent + * image registry, bottom right on top of the base image. + * + * @param key The overlay image key. Must not be <code>null</code>. + */ + protected void drawBottomRight(String key) { + if (getSize() != null) { + Point size = getSize(); + drawBottomRight(key, size.x, size.y); + } else { + // the default eclipse style guide recommendation is 16x16 + drawBottomRight(key, 16, 16); + } + } + + /** + * Draw the overlay image, found under the specified key in the parent + * image registry, bottom right on top of the base image. + * + * @param key The overlay image key. Must not be <code>null</code>. + * @param width The width of the base image. + * @param height The height of the base image. + */ + protected void drawBottomRight(String key, int width, int height) { + Image image = parentImageRegistry.get(key); + if (image != null) { + ImageData imageData = image.getImageData(); + if (imageData != null) { + int x = StrictMath.max(0, width - imageData.width); + int y = StrictMath.max(0, height - imageData.height); + drawImage(imageData, x, y); + } + } + } + + /** + * Returns the base image used for the combined image description. This + * method is called from <code>getTransparentPixel()</code> to query the + * transparent color of the palette. + * + * @return The base image or <code>null</code> if none. + */ + protected abstract Image getBaseImage(); + + /* (non-Javadoc) + * @see org.eclipse.jface.resource.CompositeImageDescriptor#getTransparentPixel() + */ + @Override + protected int getTransparentPixel() { + Image baseImage = getBaseImage(); + if (baseImage != null && baseImage.getImageData() != null) { + return baseImage.getImageData().transparentPixel; + } + return super.getTransparentPixel(); + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/DisplayUtil.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/DisplayUtil.java new file mode 100644 index 000000000..4a325c255 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/DisplayUtil.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.swt; + +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.PlatformUI; + +/** + * Utility providing convenience methods to use the SWT Display. + */ +public class DisplayUtil { + + /** + * Does what Display does in syncExec, but ensures + * that the exec is not executed if the display is + * currently being disposed or already unset. + * + * @param exec the Runnable to be executed. + * + * @see Display#asyncExec(Runnable) + * @see Runnable#run() + */ + public static void safeSyncExec(Runnable exec){ + try { + Display display = PlatformUI.getWorkbench().getDisplay(); + display.syncExec(exec); + } + catch (Exception e) { + // if display is disposed, silently ignore. + } + } + /** + * Does what Display does in timerExec, but ensures + * that the exec is not executed if the display is + * currently being disposed or already unset. + * + * @param exec the Runnable to be executed. + * @param millisec time to wait. + * + * @see Display#timerExec(int, Runnable) + * @see Runnable#run() + */ + public static void safeTimerExec(Runnable exec, int millisec){ + try { + Display display = PlatformUI.getWorkbench().getDisplay(); + display.timerExec(millisec,exec); + } + catch (Exception e) { + // if display is disposed, silently ignore. + } + } + + /** + * Does what Display does in asyncExec, but ensures + * that the exec is not executed if the display is + * currently being disposed or already unset. + * + * @param exec The Runnable to be executed. + * + * @see Display#asyncExec(Runnable) + * @see Runnable#run() + */ + public static void safeAsyncExec(Runnable exec){ + try { + Display display = PlatformUI.getWorkbench().getDisplay(); + display.asyncExec(exec); + } + catch (Exception e) { + // if display is disposed, silently ignore. + } + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/SWTControlUtil.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/SWTControlUtil.java new file mode 100644 index 000000000..0037fe080 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/SWTControlUtil.java @@ -0,0 +1,713 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.swt; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Decorations; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Link; +import org.eclipse.swt.widgets.List; +import org.eclipse.swt.widgets.Scrollable; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.PlatformUI; + +/** + * Utility providing convenience methods for use with SWT controls. + */ +public final class SWTControlUtil { + + /** + * Returns the text from the specified control. The method will return <code>null</code> + * if the control is <code>null</code> or has been already disposed. + * + * @param control The control to get the text from. + * @param The text currently set to the control or <code>null</code>. + */ + public static final String getText(Control control) { + if (control != null && !control.isDisposed()) { + if (control instanceof Button) { + return ((Button)control).getText().trim(); + } + if (control instanceof Combo) { + return ((Combo)control).getText().trim(); + } + if (control instanceof Group) { + return ((Group)control).getText().trim(); + } + if (control instanceof Label) { + return ((Label)control).getText().trim(); + } + if (control instanceof Link) { + return ((Link)control).getText().trim(); + } + if (control instanceof Text) { + return ((Text)control).getText().trim(); + } + if (control instanceof Decorations) { + return ((Decorations)control).getText(); + } + } + return null; + } + + /** + * Sets the given text to the specified control. The text will be not applied if the + * control is <code>null</code> or has been already disposed or if the given text itself + * is <code>null</code>. + * + * @param control The control the given text should be applied to. + * @param value The text to apply to the given control. + */ + public static final void setText(Control control, String value) { + if (control != null && !control.isDisposed() && value != null) { + String trimmedValue = value.trim(); + + // Avoid triggering attached listeners if the value has not changed. + String oldValue = getText(control); + if (!trimmedValue.equals(oldValue)) { + if (control instanceof Button) { + ((Button)control).setText(trimmedValue); + } + if (control instanceof Combo) { + ((Combo)control).setText(trimmedValue); + } + if (control instanceof Group) { + ((Group)control).setText(trimmedValue); + } + if (control instanceof Label) { + ((Label)control).setText(trimmedValue); + } + if (control instanceof Link) { + ((Link)control).setText(trimmedValue); + } + if (control instanceof Text) { + ((Text)control).setText(trimmedValue); + } + if (control instanceof Decorations) { + ((Decorations)control).setText(trimmedValue); + } + } + } + } + + /** + * Sets the given text to the specified control as tooltip. The tooltip text will be not + * applied if the control is <code>null</code> or has been already disposed. + * + * @param control The control the given text should be applied to. + * @param value The text to apply to the given control or <code>null</code> to reset the tooltip. + */ + public static final void setToolTipText(Control control, String value) { + if (control != null && !control.isDisposed()) { + control.setToolTipText(value); + } + } + + /** + * Sets the text of the control (Text, Combo) as tooltip if the text is + * not fully visible. + * @param control The control to set the tooltip for. + */ + public static final void setValueToolTip(Scrollable control) { + if (control != null && !control.isDisposed()) { + String text = null; + int resize = 0; + if (control instanceof Text) { + text = ((Text)control).getText().trim(); + resize = control.getBorderWidth() * 2; + } + if (control instanceof Combo) { + text = ((Combo)control).getText().trim(); + resize = (int)(control.getSize().y * 1.5) + control.getBorderWidth() * 2; + } + if (text != null) { + GC gc = new GC(control); + int width = 0; + for (int i = 0; i < text.length(); i++) { + width += gc.getAdvanceWidth(text.charAt(i)); + } + // Show the tooltip _only_ if the text itself exceeds + // the length of the control (partially shown within the control). + if (width > (control.getClientArea().width - resize)) { + control.setToolTipText(text); + } else { + control.setToolTipText(null); + } + gc.dispose(); + } + } + } + + /** + * Adds the given text to the specified control. The given text will be added in case it's not + * <code>null</code> and not empty and if the given control itself is not <code>null</code> + * and not disposed. If the given text is already within the controls drop down list, the text + * will <i>not</i> be added again to the list. + * + * @param control The control to add the given text to. + * @param value The text to add to the control. + */ + public static final void add(Control control, String value) { + add(control, value, false); + } + + /** + * Adds the given text to the specified control. The given text will be added in case it's not + * <code>null</code> and not empty and if the given control itself is not <code>null</code> + * and not disposed. If the given text is already within the controls drop down list, the text + * will <i>not</i> be added again to the list. + * + * @param control The control to add the given text to. + * @param value The text to add to the control. + * @param allowEmpty If <code>true</code>, empty values will be added to the control. Otherwise, + * empty values will be filtered out and not applied to the control. + */ + public static final void add(Control control, String value, boolean allowEmpty) { + if (control != null && !control.isDisposed() && value != null) { + if (!allowEmpty && value.trim().length() == 0) { + return; + } + if (control instanceof Combo) { + Combo combo = ((Combo)control); + if (combo.indexOf(value) == -1) { + combo.add(value); + } + } + if (control instanceof List) { + List list = ((List)control); + if (list.indexOf(value) == -1) { + list.add(value); + } + } + } + } + + /** + * Adds the given text to the specified control at the given index. If the given index is negative, + * the item index will be set to <code>0</code>. The given text will be added in case it's not + * <code>null</code> and not empty and if the given control itself is not <code>null</code> + * and not disposed. If the given text is already within the controls drop down list, the text will + * <i>not</i> be added again to the list. + * + * @param control The control to add the given text to. + * @param value The text to add to the control. + * @param index The index of the item to add to the control. + */ + public static final void add(Control control, String value, int index) { + add(control, value, index, false); + } + + /** + * Adds the given text to the specified control at the given index. If the given index is negative, + * the item index will be set to <code>0</code>. The given text will be added in case it's not + * <code>null</code> and not empty and if the given control itself is not <code>null</code> + * and not disposed. If the given text is already within the controls drop down list, the text will + * <i>not</i> be added again to the list. + * + * @param control The control to add the given text to. + * @param value The text to add to the control. + * @param index The index of the item to add to the control. + * @param allowEmpty If <code>true</code>, empty values will be added to the control. Otherwise, + * empty values will be filtered out and not applied to the control. + */ + public static final void add(Control control, String value, int index, boolean allowEmpty) { + if (control != null && !control.isDisposed() && value != null) { + if (!allowEmpty && value.trim().length() == 0) { + return; + } + if (control instanceof Combo) { + Combo combo = ((Combo)control); + if (combo.indexOf(value) == -1) { + if (index < 0) { + index = 0; + } + combo.add(value, index); + } + } + if (control instanceof List) { + List list = ((List)control); + if (list.indexOf(value) == -1) { + if (index < 0) { + index = 0; + } + list.add(value, index); + } + } + } + } + + /** + * Sets the enabled state of the given control to the given state. The state will be + * applied in case the given control is not <code>null</code> and not disposed. + * + * @param control The control to set the enabled state for. + * @param enabled <code>true</code> to enable the control, <code>false</code> otherwise. + */ + public static final void setEnabled(Control control, boolean enabled) { + if (control != null && !control.isDisposed()) { + control.setEnabled(enabled); + } + } + + /** + * Returns the enabled state of the given control. The method returns always <code>true</code> + * in case the given control is <code>null</code> or disposed. + * + * @param control The control to get the enabled state for. + * @return <code>true</code> if the control is enabled, <code>false</code> otherwise. + */ + public static final boolean isEnabled(Control control) { + if (control != null && !control.isDisposed()) { + return control.isEnabled(); + } + return true; + } + + /** + * Sets the visible state of the given control. The state will be applied in + * case the given control is not <code>null</code> and not disposed. + * + * @param control The control to set the visible state for. + * @param visible <code>True</code> to set the control visible, <code>false</code> otherwise. + */ + public static final void setVisible(Control control, boolean visible) { + if (control != null && !control.isDisposed()) { + control.setVisible(visible); + } + } + + /** + * Returns the visible state of the given control. The method returns always + * <code>true</code> in case the given control is <code>null</code> or disposed. + * + * @param control The control to set the visible state for. + * @param visible <code>True</code> to set the control visible, <code>false</code> otherwise. + */ + public static final boolean isVisible(Control control) { + if (control != null && !control.isDisposed()) { + return control.getVisible(); + } + return true; + } + + /** + * Returns the item count of the specified control. The method will return <code>0</code> + * in case the control is <code>null</code> or has been already disposed or does not + * support items. + * + * @param control The control to get the item count for. + * @return The number of items within the control or <code>-1</code>. + */ + public static final int getItemCount(Control control) { + if (control != null && !control.isDisposed()) { + if (control instanceof Combo) { + return ((Combo)control).getItemCount(); + } + if (control instanceof List) { + return ((List)control).getItemCount(); + } + } + return -1; + } + + /** + * Sets the specified items to the specified control. + * + * @param control The control to set the items to. + * @param items The array of items to set. + */ + public static final void setItems(Control control, String[] items) { + if (control != null && !control.isDisposed() && items != null) { + if (control instanceof Combo) { + ((Combo)control).setItems(items); + } + else if (control instanceof List) { + ((List)control).setItems(items); + } + } + } + + /** + * Returns the items of the specified control. The method will return an empty array + * in case the control is <code>null</code> or has been already disposed or does not + * support items. + * + * @param control The control to get the items from. + * @return The array items or and empty array. + */ + public static final String[] getItems(Control control) { + if (control != null && !control.isDisposed()) { + if (control instanceof Combo) { + return ((Combo)control).getItems(); + } + if (control instanceof List) { + return ((List)control).getItems(); + } + } + return new String[0]; + } + + /** + * Sets the text of the specified item of the specified control. + * + * @param control The control to set the item text. + * @param index The index of the item to change. + * @param value The new item text to apply. + */ + public static final void setItem(Control control, int index, String value) { + if (control != null && !control.isDisposed() && value != null) { + // The index must be within valid range + if (index >= 0 && index < getItemCount(control)) { + String trimmedValue = value.trim(); + + // Avoid triggering attached listeners if the value has not changed. + String oldValue = getItem(control, index); + if (!trimmedValue.equals(oldValue)) { + if (control instanceof Combo) { + ((Combo)control).setItem(index, trimmedValue); + } + if (control instanceof List) { + ((List)control).setItem(index, trimmedValue); + } + } + } + } + } + + /** + * Returns the text of the item at the specified index of the specified control. + * + * @param control The control to query the item text from. + * @param index The index of the item to query. + * @return The item text or <code>null</code>. + */ + public static final String getItem(Control control, int index) { + if (control != null && !control.isDisposed()) { + // The index must be within valid range + if (index >= 0 && index < getItemCount(control)) { + if (control instanceof Combo) { + return ((Combo)control).getItem(index).trim(); + } + if (control instanceof List) { + return ((List)control).getItem(index).trim(); + } + } + } + return null; + } + + /** + * Returns the selected item index of the specified control. The method will return <code>-1</code> in case + * the control is <code>null</code> or has been already disposed or does not support selections. + * + * @param control The control to get the selected item index for. + * @return The index of the selected item within the control or <code>-1</code>. + */ + public static final int getSelectionIndex(Control control) { + if (control != null && !control.isDisposed()) { + if (control instanceof Combo) { + return ((Combo)control).getSelectionIndex(); + } + if (control instanceof List) { + return ((List)control).getSelectionIndex(); + } + if (control instanceof Table) { + return ((Table)control).getSelectionIndex(); + } + } + return -1; + } + + /** + * Returns the selected item count of the specified control. The method will return <code>-1</code> in case + * the control is <code>null</code> or has been already disposed or does not support selections. + * + * @param control The control to get the selected item count for. + * @return The number of selected items within the control or <code>-1</code>. + */ + public static final int getSelectionCount(Control control) { + if (control != null && !control.isDisposed()) { + if (control instanceof List) { + return ((List)control).getSelectionCount(); + } + if (control instanceof Table) { + return ((Table)control).getSelectionCount(); + } + if (control instanceof Tree) { + return ((Tree)control).getSelectionCount(); + } + } + return -1; + } + + /** + * Removes all items of the specified control. + * + * @param control The control to remove all items from. + */ + public static final void removeAll(Control control) { + if (control != null && !control.isDisposed()) { + if (control instanceof Combo) { + ((Combo)control).removeAll(); + } + if (control instanceof List) { + ((List)control).removeAll(); + } + if (control instanceof Table) { + ((Table)control).removeAll(); + } + if (control instanceof Tree) { + ((Tree)control).removeAll(); + } + } + } + + /** + * Returns the index of the given item for the specified control. The method will return + * <code>-1</code> in case the control is <code>null</code> or has been already disposed + * or does not support items. + * + * @param control The control to lookup the item index. + * @param item The item to lookup the index for. + * @return The item index if found or <code>-1</code>. + */ + public static final int indexOf(Control control, String item) { + if (control != null && !control.isDisposed() && item != null) { + if (control instanceof Combo) { + return ((Combo)control).indexOf(item); + } + if (control instanceof List) { + return ((List)control).indexOf(item); + } + } + return -1; + } + + /** + * Selects the item with the given item index for the specified control. The method will + * return immediately in case the control is <code>null</code> or has been already + * disposed or does not support items. + * + * @param control The control to select the given item. + * @param item The item to select. + */ + public static final void select(Control control, int index) { + if (control != null && !control.isDisposed()) { + if (index >= 0 && index < getItemCount(control)) { + if (control instanceof Combo) { + ((Combo)control).select(index); + } + if (control instanceof List) { + ((List)control).select(index); + } + } + } + return; + } + + /** + * Returns the buttons selection state. + * + * @param button The button to query the selection state for. + * @return <code>true</code> if the button specified is not <code>null</code> nor disposed and selected, <code>false</code> otherwise. + */ + public static final boolean getSelection(Button button) { + if (button != null && !button.isDisposed()) { + return button.getSelection(); + } + return false; + } + + /** + * Sets the buttons selection state to the given state. + * + * @param button The button to set the selection state for. + * @param selected The button selection state to set. + */ + public static final void setSelection(Button button, boolean selected) { + if (button != null && !button.isDisposed()) { + button.setSelection(selected); + } + } + + /** + * Returns the number of pixels corresponding to the height of the given + * number of characters. + * <p> + * This methods uses the static {@link Dialog#convertHeightInCharsToPixels(org.eclipse.swt.graphics.FontMetrics, int)} + * method for calculation. + * <p> + * @param chars The number of characters + * @return The corresponding height in pixels + */ + public static int convertHeightInCharsToPixels(Control control, int chars) { + int height = 0; + if (control != null && !control.isDisposed()) { + GC gc = new GC(control); + gc.setFont(JFaceResources.getDialogFont()); + height = Dialog.convertHeightInCharsToPixels(gc.getFontMetrics(), chars); + gc.dispose(); + } + + return height; + } + + /** + * Returns the number of pixels corresponding to the width of the given + * number of characters. + * <p> + * This methods uses the static {@link Dialog#convertWidthInCharsToPixels(org.eclipse.swt.graphics.FontMetrics, int)} + * method for calculation. + * <p> + * @param chars The number of characters + * @return The corresponding width in pixels + */ + public static int convertWidthInCharsToPixels(Control control, int chars) { + int width = 0; + if (control != null && !control.isDisposed()) { + GC gc = new GC(control); + gc.setFont(JFaceResources.getDialogFont()); + width = Dialog.convertWidthInCharsToPixels(gc.getFontMetrics(), chars); + gc.dispose(); + } + + return width; + } + + /** + * Sets the focus to the given control. + * + * @param control The control to set the focus to. + * @return <code>True</code> if the control got the focus, <code>false</code> otherwise. + */ + public static boolean setFocus(Control control) { + if (control != null && !control.isDisposed()) { + return control.setFocus(); + } + return false; + } + + /** + * Sets the given color as control foreground. + * + * @param control The control. + * @param color The color. + */ + public static void setForeground(Control control, Color color) { + if (control != null && !control.isDisposed() && color != null) { + control.setForeground(color); + } + } + + /** + * Sets the given color as control background. + * + * @param control The control. + * @param color The color. + */ + public static void setBackground(Control control, Color color) { + if (control != null && !control.isDisposed() && color != null) { + control.setBackground(color); + } + } + + /** + * Sets the given image as control background image. + * + * @param control The control. + * @param image The image. + */ + public static void setBackgroundImage(Control control, Image image) { + if (control != null && !control.isDisposed() && image != null) { + control.setBackgroundImage(image); + } + } + + /* -------------------------------------------------------------------- + * + * Generate system specific checkbox images. + * + * -------------------------------------------------------------------- */ + + private static final String CHECKED = "CHECKED"; //$NON-NLS-1$ + private static final String UNCHECKED = "UNCHECKED"; //$NON-NLS-1$ + private static final String GRAYED = "GRAYED"; //$NON-NLS-1$ + private static final String ENABLED = "ENABLED"; //$NON-NLS-1$ + private static final String DISABLED = "DISABLED"; //$NON-NLS-1$ + + private static Image makeShot(Shell shell, boolean checked, boolean grayed, boolean enabled) { + shell = new Shell(shell, SWT.NO_FOCUS | SWT.NO_TRIM); + + Color greenScreen = new Color(shell.getDisplay(), 222, 223, 224); + shell.setBackground(greenScreen); + + Button button = new Button(shell, SWT.CHECK); + button.setBackground(greenScreen); + button.setSelection(grayed || checked); + button.setEnabled(enabled); + button.setGrayed(grayed); + + button.setLocation(0, 0); + Point bsize = button.computeSize(SWT.DEFAULT, SWT.DEFAULT); + + button.setSize(bsize); + shell.setSize(bsize); + + shell.open(); + GC gc = new GC(shell); + Image image = new Image(shell.getDisplay(), bsize.x, bsize.y); + gc.copyArea(image, 0, 0); + gc.dispose(); + + ImageData imageData = image.getImageData(); + imageData.transparentPixel = imageData.palette.getPixel(greenScreen + .getRGB()); + image = new Image(shell.getDisplay(), imageData); + shell.close(); + + return image; + } + + public static synchronized Image getCheckBoxImage(boolean checked, boolean grayed, boolean enabled) { + String key = (SWTControlUtil.class.getName() + "_" + //$NON-NLS-1$ + ((checked || grayed) ? CHECKED : UNCHECKED) + "_" + //$NON-NLS-1$ + (grayed ? GRAYED + "_" : "") + //$NON-NLS-1$ //$NON-NLS-2$ + (enabled ? ENABLED : DISABLED)); + + Image image = JFaceResources.getImageRegistry().get(key); + try { + if (image == null || image.getImageData().data == null) { + Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); + image = makeShot(shell, checked||grayed, grayed, enabled); + if (image != null && image.getImageData().data != null) { + JFaceResources.getImageRegistry().put(key, image); + } + } + } + catch (Exception e) { + } + + return image; + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/activator/UIPlugin.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/activator/UIPlugin.java new file mode 100644 index 000000000..50f579117 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/activator/UIPlugin.java @@ -0,0 +1,65 @@ +/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.swt.activator;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class UIPlugin extends AbstractUIPlugin {
+ // The shared instance
+ private static UIPlugin plugin;
+
+ /**
+ * The constructor
+ */
+ public UIPlugin() {
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static UIPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Convenience method which returns the unique identifier of this plugin.
+ */
+ public static String getUniqueIdentifier() {
+ if (getDefault() != null && getDefault().getBundle() != null) {
+ return getDefault().getBundle().getSymbolicName();
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/listener/AbstractCellPaintListener.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/listener/AbstractCellPaintListener.java new file mode 100644 index 000000000..bdd6d9333 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/listener/AbstractCellPaintListener.java @@ -0,0 +1,211 @@ +/** + * AbstractCellPaintListener.java + * Created on Aug 21, 2011 + * + * Copyright (c) 2011 Wind River Systems, Inc. + * + * The right to copy, distribute, modify, or otherwise make use + * of this software may be licensed only pursuant to the terms + * of an applicable Wind River license agreement. + */ +package org.eclipse.tcf.te.ui.swt.listener; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.swt.widgets.Widget; + +/** + * Abstract cell paint listener implementation + */ +public abstract class AbstractCellPaintListener implements Listener { + + private final int[] columns; + + /** + * Constructor. + * @param colums The valid columns. + * @param widget The widget. + */ + public AbstractCellPaintListener(Widget widget, int... columns) { + this.columns = columns; + register(widget); + } + + /** + * Add this listener to the widget. + * @param widget The widget. + */ + protected void register(Widget widget) { + if (widget != null && !widget.isDisposed()) { + widget.addListener(SWT.MeasureItem, this); + widget.addListener(SWT.PaintItem, this); + widget.addDisposeListener(new DisposeListener() { + @Override + public void widgetDisposed(DisposeEvent e) { + deregister(e.widget); + } + }); + } + } + + /** + * Remove this listener from the widget. + * @param widget The widget. + */ + protected void deregister(Widget widget) { + if (widget != null) { + widget.removeListener(SWT.MeasureItem, this); + widget.removeListener(SWT.PaintItem, this); + } + } + + /* (non-Javadoc) + * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event) + */ + @Override + public void handleEvent(Event event) { + // Check if the event type is handled. + if (!isHandledEventType(event.type)) { + return; + } + + // We can paint something only if the item is available + if (event.item instanceof Item) { + // Check if the table item is valid + if (isValid(event)) { + // Forward to the event type specific handler methods + switch (event.type) { + case SWT.MeasureItem: + doHandleMeasureItemEvent(event); + break; + case SWT.PaintItem: + doHandlePaintItemEvent(event); + break; + } + } + } + } + + /** + * Returns if or if not the given event type is handled by this handler. + * <p> + * The default implementation accepts {@link SWT#MeasureItem} and {@link SWT#PaintItem}. + * + * @param type The event type. + * @return <code>True</code> if the event type is handled by this handler, <code>false</code> otherwise. + */ + protected boolean isHandledEventType(int type) { + return SWT.MeasureItem == type || SWT.PaintItem == type; + } + + /** + * Handle the measure item event. + * @param event The event. + */ + protected void doHandleMeasureItemEvent(Event event) { + Assert.isNotNull(event); + + // Get the image to draw. + Image image = getImageToDraw((Item)event.item, event.index); + // We have to measure anything only if the returned image is not null. + if (image != null) { + // Width must be minimum image width + 1 pixels at each side + event.width = Math.max(event.width, image.getImageData().width + 2); + // Height must be minimum image width + 1 pixels at each side + event.height = Math.max(event.height, image.getImageData().height + 2); + } + } + + /** + * Handle the paint item event. + * @param event The event. + */ + protected void doHandlePaintItemEvent(Event event) { + Assert.isNotNull(event); + + // Get the image to draw. + Image image = getImageToDraw((Item)event.item, event.index); + // We have to draw anything only if the returned image is not null. + if (image != null) { + Point point = getPaintOrigin(event, image); + // Paint the image + event.gc.drawImage(image, point.x, point.y); + } + } + + /** + * Get the origin where the image should be painted. + * @param event The event. + * @param image The image. + * @return The origin. + */ + protected abstract Point getPaintOrigin(Event event, Image image); + + /** + * Get the width of the widget where the image to draw into. + * @param event The event. + * @return The width. + */ + protected int getWidgetWidth(Event event) { + if (event.widget instanceof Table) { + TableColumn column = ((Table)event.widget).getColumn(event.index); + return column.getWidth(); + } + else if (event.widget instanceof Tree) { + TreeColumn column = ((Tree)event.widget).getColumn(event.index); + return column.getWidth(); + } + return event.width; + } + + /** + * Get the image to draw + * @param item The item to draw the image for. + * @param columnIndex The column index. + * @return The image or <code>null</code>. + */ + protected abstract Image getImageToDraw(Item item, int columnIndex); + + /** + * Returns if or if not the given events data is valid. + * Subclass implementers may check if the associated data object + * is matching and expected data type. + * + * @param event The event. Must not be <code>null</code>. + * @return <code>True</code> if the events data is valid, <code>false</code> otherwise. + */ + protected boolean isValid(Event event) { + return (event.item != null && isPaintImageInColumn(event.index) && + ((event.widget instanceof Table && event.item instanceof TableItem) || + (event.widget instanceof Tree && event.item instanceof TreeItem))); + } + + /** + * Returns if or if not the managed image shall be painted to the + * given column. + * + * @param columnIndex The column index of the current column. + * @return <code>True</code> if the image shall be painted, <code>false</code> otherwise. + */ + protected boolean isPaintImageInColumn(int columnIndex) { + for (int col : columns) { + if (col == columnIndex) { + return true; + } + } + return false; + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/listener/AbstractCheckBoxCellPaintListener.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/listener/AbstractCheckBoxCellPaintListener.java new file mode 100644 index 000000000..4dec98884 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/listener/AbstractCheckBoxCellPaintListener.java @@ -0,0 +1,91 @@ +/** + * AbstractCheckBoxCellPaintListener.java + * Created on Aug 21, 2011 + * + * Copyright (c) 2011 Wind River Systems, Inc. + * + * The right to copy, distribute, modify, or otherwise make use + * of this software may be licensed only pursuant to the terms + * of an applicable Wind River license agreement. + */ +package org.eclipse.tcf.te.ui.swt.listener; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.Widget; +import org.eclipse.tcf.te.ui.swt.SWTControlUtil; + +/** + * Abstract check box cell paint listener implementation. + */ +public abstract class AbstractCheckBoxCellPaintListener extends AbstractCellPaintListener { + + private static final int ENABLED = 1; + private static final int CHECKED = 2; + private static final int TRISTATE = 4; + + protected static final int STATE_NONE = -1; + protected static final int STATE_ENABLED_CHECKED = ENABLED | CHECKED; + protected static final int STATE_ENABLED_UNCHECKED = ENABLED; + protected static final int STATE_ENABLED_TRISTATE = ENABLED | TRISTATE; + protected static final int STATE_DISABLED_CHECKED = CHECKED; + protected static final int STATE_DISABLED_UNCHECKED = 0; + protected static final int STATE_DISABLED_TRISTATE = TRISTATE; + + /** + * Constructor. + * + * @param columns The valid columns. + * @param widget The widget. + */ + public AbstractCheckBoxCellPaintListener(Widget widget, int... columns) { + super(widget, columns); + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.swt.listener.AbstractCellPaintListener#getPaintOrigin(org.eclipse.swt.widgets.Event, org.eclipse.swt.graphics.Image) + */ + @Override + protected Point getPaintOrigin(Event event, Image image) { + // Determine host platform + boolean isWindowsHost = System.getProperty("os.name","").toLowerCase().startsWith("windows"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + // Center the image horizontally within the column + int x = event.x + (getWidgetWidth(event)/2 - image.getImageData().width / 2); + // Center the image vertically within the column + int y = isWindowsHost ? event.y : event.y + event.height - (image.getImageData().height + 4); + return new Point(x, y); + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.swt.listener.AbstractCellPaintListener#getImageToDraw(org.eclipse.swt.widgets.Item, int) + */ + @Override + protected Image getImageToDraw(Item item, int columnIndex) { + Assert.isNotNull(item); + + // If the image shall be painted to the current column + if (isPaintImageInColumn(columnIndex)) { + // Check which image to paint + int state = getCheckBoxState(item.getData(), columnIndex); + if (state >= 0) { + return SWTControlUtil.getCheckBoxImage((state & CHECKED) > 0, (state & TRISTATE) > 0, (state & ENABLED) > 0); + } + } + + return null; + } + + /** + * Returns the state for the check box. + * + * @param data The associated event data or <code>null</code>: + * @param columnIndex The column index of the current column. + * + * @return The state for the check box. + */ + protected abstract int getCheckBoxState(Object data, int columnIndex); + +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/listener/AbstractDecorationCellPaintListener.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/listener/AbstractDecorationCellPaintListener.java new file mode 100644 index 000000000..ddaf3ce6b --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/listener/AbstractDecorationCellPaintListener.java @@ -0,0 +1,97 @@ +/** + * AbstractDecorationCellPaintListener.java + * Created on Aug 21, 2011 + * + * Copyright (c) 2011 Wind River Systems, Inc. + * + * The right to copy, distribute, modify, or otherwise make use + * of this software may be licensed only pursuant to the terms + * of an applicable Wind River license agreement. + */ +package org.eclipse.tcf.te.ui.swt.listener; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.fieldassist.FieldDecoration; +import org.eclipse.jface.fieldassist.FieldDecorationRegistry; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.Widget; + +/** + * Abstract decoration cell paint listener implementation + */ +public abstract class AbstractDecorationCellPaintListener extends AbstractCellPaintListener { + + public static final int STATE_NONE = IMessageProvider.NONE; + public static final int STATE_INFO = IMessageProvider.INFORMATION; + public static final int STATE_WARNING = IMessageProvider.WARNING; + public static final int STATE_ERROR = IMessageProvider.ERROR; + + /** + * Constructor. + * @param colums The valid columns. + * @param widget The widget. + */ + public AbstractDecorationCellPaintListener(Widget widget, int... columns) { + super(widget, columns); + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.swt.listener.AbstractCellPaintListener#getPaintOrigin(org.eclipse.swt.widgets.Event, org.eclipse.swt.graphics.Image) + */ + @Override + protected Point getPaintOrigin(Event event, Image image) { + return new Point(event.x, event.y); + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.swt.listener.AbstractCellPaintListener#getImageToDraw(org.eclipse.swt.widgets.Item, int) + */ + @Override + protected Image getImageToDraw(Item item, int columnIndex) { + Assert.isNotNull(item); + + // If the image shall be painted to the current column + if (isPaintImageInColumn(columnIndex)) { + // Check which image to paint + int state = getDecorationState(item.getData(), columnIndex); + if (state >= 0) { + String decorationId = null; + switch (state) { + case STATE_INFO: + decorationId = FieldDecorationRegistry.DEC_INFORMATION; + break; + case STATE_WARNING: + decorationId = FieldDecorationRegistry.DEC_WARNING; + break; + case STATE_ERROR: + decorationId = FieldDecorationRegistry.DEC_ERROR; + break; + } + if (decorationId != null) { + // Get the field decoration + FieldDecoration fieldDeco = FieldDecorationRegistry.getDefault().getFieldDecoration(decorationId); + if (fieldDeco != null) { + return fieldDeco.getImage(); + } + } + } + } + + return null; + } + + /** + * Returns the state for the decoration. + * + * @param data The associated event data or <code>null</code>: + * @param columnIndex The column index of the current column. + * + * @return The state for the decoration. + */ + protected abstract int getDecorationState(Object data, int columnIndex); + +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/nls/Messages.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/nls/Messages.java new file mode 100644 index 000000000..a5b418f7e --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/nls/Messages.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.swt.nls; + +import java.lang.reflect.Field; + +import org.eclipse.osgi.util.NLS; + +/** + * Common SWT and JFace Helper plug-in externalized strings management. + */ +public class Messages extends NLS { + + // The plug-in resource bundle name + private static final String BUNDLE_NAME = "org.eclipse.tcf.te.ui.swt.nls.Messages"; //$NON-NLS-1$ + + /** + * Static constructor. + */ + static { + // Load message values from bundle file + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + /** + * Returns if or if not this NLS manager contains a constant for + * the given externalized strings key. + * + * @param key The externalized strings key or <code>null</code>. + * @return <code>True</code> if a constant for the given key exists, <code>false</code> otherwise. + */ + public static boolean hasString(String key) { + if (key != null) { + try { + Field field = Messages.class.getDeclaredField(key); + return field != null; + } catch (NoSuchFieldException e) { /* ignored on purpose */ } + } + + return false; + } + + /** + * Returns the corresponding string for the given externalized strings + * key or <code>null</code> if the key does not exist. + * + * @param key The externalized strings key or <code>null</code>. + * @return The corresponding string or <code>null</code>. + */ + public static String getString(String key) { + if (key != null) { + try { + Field field = Messages.class.getDeclaredField(key); + if (field != null) { + return (String)field.get(null); + } + } catch (Exception e) { /* ignored on purpose */ } + } + + return null; + } + + // **** Declare externalized string id's down here ***** + + public static String NoteCompositeHelper_note_label; + + public static String OptionalMessageDialog_doNotShowAgain_label; + public static String OptionalMessageDialog_rememberMyDecision_label; +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/nls/Messages.properties new file mode 100644 index 000000000..18de15a8c --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/nls/Messages.properties @@ -0,0 +1,9 @@ +# +# org.eclipse.tcf.te.ui.swt +# Externalized Strings. +# + +NoteCompositeHelper_note_label=Note: + +OptionalMessageDialog_doNotShowAgain_label=Do not show again +OptionalMessageDialog_rememberMyDecision_label=Remember my decision diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/widgets/NoteCompositeHelper.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/widgets/NoteCompositeHelper.java new file mode 100644 index 000000000..ee48fa805 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/widgets/NoteCompositeHelper.java @@ -0,0 +1,144 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.swt.widgets; + +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.tcf.te.ui.swt.SWTControlUtil; +import org.eclipse.tcf.te.ui.swt.nls.Messages; + +/** + * A helper class to create a composite with a highlighted note + * entry and a message text. + */ +public class NoteCompositeHelper { + + /** + * The common label text to show on a note. Defaults to "Note:". + */ + public static final String NOTE_LABEL = Messages.NoteCompositeHelper_note_label; + + private static class NoteComposite extends Composite { + + public NoteComposite(Composite parent, int style) { + super(parent, style); + } + + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + Control[] childs = getChildren(); + for (int iChild = 0; iChild < childs.length; iChild++) { + Control child = childs[iChild]; + child.setEnabled(enabled); + } + } + } + + /** + * Creates a composite with a highlighted Note entry and a message text. + * This is designed to take up the full width of the page. + * + * @see PreferencePage#createNoteComposite, this is a plain copy of that! + * @param font + * the font to use + * @param composite + * the parent composite + * @param title + * the title of the note + * @param message + * the message for the note + * @return the composite for the note + */ + public static Composite createNoteComposite(Font font, Composite composite, String title, String message) { + Composite messageComposite = new NoteComposite(composite, SWT.NONE); + + GridLayout messageLayout = new GridLayout(); + messageLayout.numColumns = 2; + messageLayout.marginWidth = 0; + messageLayout.marginHeight = 0; + messageComposite.setLayout(messageLayout); + + GridData layoutData = new GridData(GridData.HORIZONTAL_ALIGN_FILL); + if (composite.getLayout() instanceof GridLayout) { + layoutData.horizontalSpan = ((GridLayout) composite.getLayout()).numColumns; + } + messageComposite.setLayoutData(layoutData); + messageComposite.setFont(font); + + final Label noteLabel = new Label(messageComposite, SWT.BOLD); + noteLabel.setText(title); + noteLabel.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT)); + noteLabel.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING)); + + final IPropertyChangeListener fontListener = new IPropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent event) { + // Note: This is actually wrong but the same as in platforms + // PreferencePage + if (JFaceResources.BANNER_FONT.equals(event.getProperty())) { + noteLabel.setFont(JFaceResources.getFont(JFaceResources.BANNER_FONT)); + } + } + }; + JFaceResources.getFontRegistry().addListener(fontListener); + noteLabel.addDisposeListener(new DisposeListener() { + @Override + public void widgetDisposed(DisposeEvent event) { + JFaceResources.getFontRegistry().removeListener(fontListener); + } + }); + + Label messageLabel = new Label(messageComposite, SWT.WRAP); + messageLabel.setText(message); + messageLabel.setFont(font); + + /** + * Set the controls style to FILL_HORIZONTAL making it multi-line if + * needed + */ + layoutData = new GridData(GridData.FILL_HORIZONTAL); + layoutData.widthHint = SWTControlUtil.convertWidthInCharsToPixels(messageLabel, 65); + messageLabel.setLayoutData(layoutData); + + return messageComposite; + } + + /** + * change the text of the second label + * + * @param messageComposite + * the NoteComposite that gets returned from createNoteComposite + * @param msg + * the new text + */ + public static void setMessage(Composite messageComposite, String msg) { + if (messageComposite instanceof NoteComposite) { + Control[] children = messageComposite.getChildren(); + if (children.length == 2) { + Control c = children[1]; + if (c instanceof Label) { + ((Label) c).setText(msg); + messageComposite.pack(); + } + } + } + } +} |