Mercurial > projects > dwt2
diff org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/MessageManager.d @ 12:bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sat, 14 Mar 2009 18:23:29 +0100 |
parents | |
children | dbfb303e8fb0 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/MessageManager.d Sat Mar 14 18:23:29 2009 +0100 @@ -0,0 +1,672 @@ +/******************************************************************************* + * Copyright (c) 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Port to the D programming language: + * Frank Benoit <benoit@tionex.de> + ******************************************************************************/ + +module org.eclipse.ui.internal.forms.MessageManager; + +import org.eclipse.ui.internal.forms.Messages; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CLabel; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.fieldassist.ControlDecoration; +import org.eclipse.jface.fieldassist.FieldDecoration; +import org.eclipse.jface.fieldassist.FieldDecorationRegistry; +import org.eclipse.ui.forms.IMessage; +import org.eclipse.ui.forms.IMessageManager; +import org.eclipse.ui.forms.IMessagePrefixProvider; +import org.eclipse.ui.forms.widgets.Hyperlink; +import org.eclipse.ui.forms.widgets.ScrolledForm; + +import java.lang.all; +import java.util.Enumeration; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Set; + +import tango.util.Convert; +import tango.text.Text; +import tango.io.model.IFile; + +/** + * @see IMessageManager + */ + +public class MessageManager : IMessageManager { + + private static DefaultPrefixProvider DEFAULT_PREFIX_PROVIDER_; + private static DefaultPrefixProvider DEFAULT_PREFIX_PROVIDER(){ + if( DEFAULT_PREFIX_PROVIDER_ is null ){ + synchronized(MessageManager.classinfo){ + if( DEFAULT_PREFIX_PROVIDER_ is null ){ + DEFAULT_PREFIX_PROVIDER_ = new DefaultPrefixProvider(); + } + } + } + return DEFAULT_PREFIX_PROVIDER_; + } + private ArrayList messages; + private Hashtable decorators; + private bool autoUpdate = true; + private ScrolledForm scrolledForm; + private IMessagePrefixProvider prefixProvider; + private int decorationPosition = SWT.LEFT | SWT.BOTTOM; + + private static FieldDecoration standardError_; + private static FieldDecoration standardError(){ + if( standardError_ is null ){ + synchronized(MessageManager.classinfo){ + if( standardError_ is null ){ + standardError_ = FieldDecorationRegistry + .getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_ERROR); + } + } + } + return standardError_; + } + + private static FieldDecoration standardWarning_; + private static FieldDecoration standardWarning(){ + if( standardWarning_ is null ){ + synchronized(MessageManager.classinfo){ + if( standardWarning_ is null ){ + standardWarning_ = FieldDecorationRegistry + .getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_WARNING); + } + } + } + return standardWarning_; + } + + private static FieldDecoration standardInformation_; + private static FieldDecoration standardInformation(){ + if( standardInformation_ is null ){ + synchronized(MessageManager.classinfo){ + if( standardInformation_ is null ){ + standardInformation_ = FieldDecorationRegistry + .getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_INFORMATION); + } + } + } + return standardInformation_; + } + + private static String[] SINGLE_MESSAGE_SUMMARY_KEYS_; + private static String[] SINGLE_MESSAGE_SUMMARY_KEYS(){ + if( SINGLE_MESSAGE_SUMMARY_KEYS_ is null ){ + synchronized(MessageManager.classinfo){ + if( SINGLE_MESSAGE_SUMMARY_KEYS_ is null ){ + SINGLE_MESSAGE_SUMMARY_KEYS_ = [ + Messages.MessageManager_sMessageSummary, + Messages.MessageManager_sMessageSummary, + Messages.MessageManager_sWarningSummary, + Messages.MessageManager_sErrorSummary ]; + } + } + } + return SINGLE_MESSAGE_SUMMARY_KEYS_; + } + + private static String[] MULTIPLE_MESSAGE_SUMMARY_KEYS_; + private static String[] MULTIPLE_MESSAGE_SUMMARY_KEYS(){ + if( MULTIPLE_MESSAGE_SUMMARY_KEYS_ is null ){ + synchronized(MessageManager.classinfo){ + if( MULTIPLE_MESSAGE_SUMMARY_KEYS_ is null ){ + MULTIPLE_MESSAGE_SUMMARY_KEYS_ = [ + Messages.MessageManager_pMessageSummary, + Messages.MessageManager_pMessageSummary, + Messages.MessageManager_pWarningSummary, + Messages.MessageManager_pErrorSummary ]; + } + } + } + return MULTIPLE_MESSAGE_SUMMARY_KEYS_; + } + + static class Message : IMessage { + Control control; + Object data; + Object key; + String message; + int type; + String prefix; + + this(Object key, String message, int type, Object data) { + this.key = key; + this.message = message; + this.type = type; + this.data = data; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.dialogs.IMessage#getKey() + */ + public Object getKey() { + return key; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.dialogs.IMessageProvider#getMessage() + */ + public String getMessage() { + return message; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.dialogs.IMessageProvider#getMessageType() + */ + public int getMessageType() { + return type; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.forms.messages.IMessage#getControl() + */ + public Control getControl() { + return control; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.forms.messages.IMessage#getData() + */ + public Object getData() { + return data; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.forms.messages.IMessage#getPrefix() + */ + public String getPrefix() { + return prefix; + } + } + + static class DefaultPrefixProvider : IMessagePrefixProvider { + + public String getPrefix(Control c) { + Composite parent = c.getParent(); + Control[] siblings = parent.getChildren(); + for (int i = 0; i < siblings.length; i++) { + if (siblings[i] is c) { + // this is us - go backward until you hit + // a label-like widget + for (int j = i - 1; j >= 0; j--) { + Control label = siblings[j]; + String ltext = null; + if ( auto l = cast(Label)label ) { + ltext = l.getText(); + } else if ( auto hl = cast(Hyperlink)label ) { + ltext = hl.getText(); + } else if ( auto cl = cast(CLabel)label ) { + ltext = cl.getText(); + } + if (ltext !is null) { + if (!ltext.endsWith(":")) //$NON-NLS-1$ + return ltext ~ ": "; //$NON-NLS-1$ + return ltext ~ " "; //$NON-NLS-1$ + } + } + break; + } + } + return null; + } + } + + class ControlDecorator { + private ControlDecoration decoration; + private ArrayList controlMessages; + private String prefix; + + this(Control control) { + controlMessages = new ArrayList(); + this.decoration = new ControlDecoration(control, decorationPosition, scrolledForm.getBody()); + } + + public bool isDisposed() { + return decoration.getControl() is null; + } + + void updatePrefix() { + prefix = null; + } + + void updatePosition() { + Control control = decoration.getControl(); + decoration.dispose(); + this.decoration = new ControlDecoration(control, decorationPosition, scrolledForm.getBody()); + update(); + } + + String getPrefix() { + if (prefix is null) + createPrefix(); + return prefix; + } + + private void createPrefix() { + if (prefixProvider is null) { + prefix = ""; //$NON-NLS-1$ + return; + } + prefix = prefixProvider.getPrefix(decoration.getControl()); + if (prefix is null) + // make a prefix anyway + prefix = ""; //$NON-NLS-1$ + } + + void addAll(ArrayList target) { + target.addAll(controlMessages); + } + + void addMessage(Object key, String text, Object data, int type) { + Message message = this.outer.addMessage(getPrefix(), key, + text, data, type, controlMessages); + message.control = decoration.getControl(); + if (isAutoUpdate()) + update(); + } + + bool removeMessage(Object key) { + Message message = findMessage(key, controlMessages); + if (message !is null) { + controlMessages.remove(message); + if (isAutoUpdate()) + update(); + } + return message !is null; + } + + bool removeMessages() { + if (controlMessages.isEmpty()) + return false; + controlMessages.clear(); + if (isAutoUpdate()) + update(); + return true; + } + + public void update() { + if (controlMessages.isEmpty()) { + decoration.setDescriptionText(null); + decoration.hide(); + } else { + ArrayList peers = createPeers(controlMessages); + int type = (cast(IMessage) peers.get(0)).getMessageType(); + String description = createDetails(createPeers(peers), true); + if (type is IMessageProvider.ERROR) + decoration.setImage(standardError.getImage()); + else if (type is IMessageProvider.WARNING) + decoration.setImage(standardWarning.getImage()); + else if (type is IMessageProvider.INFORMATION) + decoration.setImage(standardInformation.getImage()); + decoration.setDescriptionText(description); + decoration.show(); + } + } + } + + /** + * Creates a new instance of the message manager that will work with the + * provided form. + * + * @param scrolledForm + * the form to control + */ + public this(ScrolledForm scrolledForm) { + prefixProvider = DEFAULT_PREFIX_PROVIDER; + messages = new ArrayList(); + decorators = new Hashtable(); + this.scrolledForm = scrolledForm; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.forms.IMessageManager#addMessage(java.lang.Object, + * java.lang.String, int) + */ + public void addMessage(Object key, String messageText, Object data, int type) { + addMessage(null, key, messageText, data, type, messages); + if (isAutoUpdate()) + updateForm(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.forms.IMessageManager#addMessage(java.lang.Object, + * java.lang.String, int, org.eclipse.swt.widgets.Control) + */ + public void addMessage(Object key, String messageText, Object data, + int type, Control control) { + ControlDecorator dec = cast(ControlDecorator) decorators.get(control); + + if (dec is null) { + dec = new ControlDecorator(control); + decorators.put(control, dec); + } + dec.addMessage(key, messageText, data, type); + if (isAutoUpdate()) + updateForm(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.forms.IMessageManager#removeMessage(java.lang.Object) + */ + public void removeMessage(Object key) { + Message message = findMessage(key, messages); + if (message !is null) { + messages.remove(message); + if (isAutoUpdate()) + updateForm(); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.forms.IMessageManager#removeMessages() + */ + public void removeMessages() { + if (!messages.isEmpty()) { + messages.clear(); + if (isAutoUpdate()) + updateForm(); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.forms.IMessageManager#removeMessage(java.lang.Object, + * org.eclipse.swt.widgets.Control) + */ + public void removeMessage(Object key, Control control) { + ControlDecorator dec = cast(ControlDecorator) decorators.get(control); + if (dec is null) + return; + if (dec.removeMessage(key)) + if (isAutoUpdate()) + updateForm(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.forms.IMessageManager#removeMessages(org.eclipse.swt.widgets.Control) + */ + public void removeMessages(Control control) { + ControlDecorator dec = cast(ControlDecorator) decorators.get(control); + if (dec !is null) { + if (dec.removeMessages()) { + if (isAutoUpdate()) + updateForm(); + } + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.forms.IMessageManager#removeAllMessages() + */ + public void removeAllMessages() { + bool needsUpdate = false; + for (Enumeration enm = decorators.elements(); enm.hasMoreElements();) { + ControlDecorator control = cast(ControlDecorator) enm.nextElement(); + if (control.removeMessages()) + needsUpdate = true; + } + if (!messages.isEmpty()) { + messages.clear(); + needsUpdate = true; + } + if (needsUpdate && isAutoUpdate()) + updateForm(); + } + + /* + * Adds the message if it does not already exist in the provided list. + */ + + private Message addMessage(String prefix, Object key, String messageText, + Object data, int type, ArrayList list) { + Message message = findMessage(key, list); + if (message is null) { + message = new Message(key, messageText, type, data); + message.prefix = prefix; + list.add(message); + } else { + message.message = messageText; + message.type = type; + message.data = data; + } + return message; + } + + /* + * Finds the message with the provided key in the provided list. + */ + + private Message findMessage(Object key, ArrayList list) { + for (int i = 0; i < list.size(); i++) { + Message message = cast(Message) list.get(i); + if (message.getKey().opEquals(key)) + return message; + } + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.forms.IMessageManager#update() + */ + public void update() { + // Update decorations + for (Iterator iter = decorators.values().iterator(); iter.hasNext();) { + ControlDecorator dec = cast(ControlDecorator) iter.next(); + dec.update(); + } + // Update the form + updateForm(); + } + + /* + * Updates the container by rolling the messages up from the controls. + */ + + private void updateForm() { + ArrayList mergedList = new ArrayList(); + mergedList.addAll(messages); + for (Enumeration enm = decorators.elements(); enm.hasMoreElements();) { + ControlDecorator dec = cast(ControlDecorator) enm.nextElement(); + dec.addAll(mergedList); + } + update(mergedList); + } + + private void update(ArrayList mergedList) { + pruneControlDecorators(); + if (scrolledForm.getForm().getHead().getBounds().height is 0 || mergedList.isEmpty() || mergedList is null) { + scrolledForm.setMessage(null, IMessageProvider.NONE); + return; + } + ArrayList peers = createPeers(mergedList); + int maxType = (cast(IMessage) peers.get(0)).getMessageType(); + String messageText; + IMessage[] array = arraycast!(IMessage)( peers + .toArray()); + if (peers.size() is 1 && (cast(Message) peers.get(0)).prefix is null) { + // a single message + IMessage message = cast(IMessage) peers.get(0); + messageText = message.getMessage(); + scrolledForm.setMessage(messageText, maxType, array); + } else { + // show a summary message for the message + // and list of errors for the details + if (peers.size() > 1) + messageText = Messages.bind( + MULTIPLE_MESSAGE_SUMMARY_KEYS[maxType], + [ to!(String)(peers.size()) ]); //$NON-NLS-1$ + else + messageText = SINGLE_MESSAGE_SUMMARY_KEYS[maxType]; + scrolledForm.setMessage(messageText, maxType, array); + } + } + + private static String getFullMessage(IMessage message) { + if (message.getPrefix() is null) + return message.getMessage(); + return message.getPrefix() ~ message.getMessage(); + } + + private ArrayList createPeers(ArrayList messages) { + ArrayList peers = new ArrayList(); + int maxType = 0; + for (int i = 0; i < messages.size(); i++) { + Message message = cast(Message) messages.get(i); + if (message.type > maxType) { + peers.clear(); + maxType = message.type; + } + if (message.type is maxType) + peers.add(message); + } + return peers; + } + + private String createDetails(ArrayList messages, bool excludePrefix) { + auto txt = new tango.text.Text.Text!(char); + + for (int i = 0; i < messages.size(); i++) { + if (i > 0) + txt.append( FileConst.NewlineString ); + IMessage m = cast(IMessage) messages.get(i); + txt.append(excludePrefix ? m.getMessage() : getFullMessage(m)); + } + return txt.toString(); + } + + public static String createDetails(IMessage[] messages) { + if (messages is null || messages.length is 0) + return null; + auto txt = new tango.text.Text.Text!(char); + + for (int i = 0; i < messages.length; i++) { + if (i > 0) + txt.append( FileConst.NewlineString ); + txt.append(getFullMessage(messages[i])); + } + return txt.toString(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.forms.IMessageManager#createSummary(org.eclipse.ui.forms.IMessage[]) + */ + public String createSummary(IMessage[] messages) { + return createDetails(messages); + } + + private void pruneControlDecorators() { + for (Iterator iter = decorators.values().iterator(); iter.hasNext();) { + ControlDecorator dec = cast(ControlDecorator) iter.next(); + if (dec.isDisposed()) + iter.remove(); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.forms.IMessageManager#getMessagePrefixProvider() + */ + public IMessagePrefixProvider getMessagePrefixProvider() { + return prefixProvider; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.forms.IMessageManager#setMessagePrefixProvider(org.eclipse.ui.forms.IMessagePrefixProvider) + */ + public void setMessagePrefixProvider(IMessagePrefixProvider provider) { + this.prefixProvider = provider; + for (Iterator iter = decorators.values().iterator(); iter.hasNext();) { + ControlDecorator dec = cast(ControlDecorator) iter.next(); + dec.updatePrefix(); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.forms.IMessageManager#getDecorationPosition() + */ + public int getDecorationPosition() { + return decorationPosition; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.forms.IMessageManager#setDecorationPosition(int) + */ + public void setDecorationPosition(int position) { + this.decorationPosition = position; + for (Iterator iter = decorators.values().iterator(); iter.hasNext();) { + ControlDecorator dec = cast(ControlDecorator) iter.next(); + dec.updatePosition(); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.forms.IMessageManager#isAutoUpdate() + */ + public bool isAutoUpdate() { + return autoUpdate; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.forms.IMessageManager#setAutoUpdate(bool) + */ + public void setAutoUpdate(bool autoUpdate) { + bool needsUpdate = !this.autoUpdate && autoUpdate; + this.autoUpdate = autoUpdate; + if (needsUpdate) + update(); + } +}