Community
Participate
Working Groups
I am building an RCP app using the latest 3.3 APIs. I would like to reuse some portions of my Forms-based views and editors in wizards, including validation message handling. The behavior of the default MessageManager class is inappropriate, since it places summary messages in the form heading rather than the title area of the wizard dialog. I tried to implement a workaround, but this is quite difficult with the current API. The IMessageManager.createSummary() method is tantalizing, but I have no way to access the needed IMessage[] parameter. An ideal solution would show only one message at a time, following the example of the JDT New Class wizard. I would also like some kind of event mechanism to notify me of changes to the validation state. (I can work around the notification problem more easily, since my own code is calling addMessage() etc.)
Please attach a patch with your suggested implementation. We won't be looking at this in 3.3 as we are feature frozen now
I have implemented a workaround locally by brute-force copy-paste of the MessageManager source. Since all of the internals of the class are marked private, I don't know what the "proper" way to extend this class might be. It's my understanding that the API freeze rules permit changes to internal classes that have minimal or no impact on API behavior. I believe that this change would qualify. The key changes are: 1. Create a new class WizardMessageManager extends MessageManager. 2. Add a field "WizardPage wizardPage" and add it as a parameter to the constructor. 3. Override the update(ArrayList) method with this implementation: private void update(ArrayList mergedList) { pruneControlDecorators(); if (mergedList.isEmpty() || mergedList == null) { // XXX: put the messages in the wizard page, instead of the form heading wizardPage.setErrorMessage(null); // scrolledForm.setMessage(null, IMessageProvider.NONE); return; } ArrayList peers = createPeers(mergedList); int maxType = ((IMessage) peers.get(0)).getMessageType(); String messageText; IMessage[] array = (IMessage[]) peers .toArray(new IMessage[peers.size()]); if (peers.size() == 1 && ((Message) peers.get(0)).prefix == null) { // a single message IMessage message = (IMessage) peers.get(0); messageText = message.getMessage(); // XXX: put the messages in the wizard page, instead of the form heading wizardPage.setErrorMessage(messageText); // 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], new String[] { peers.size() + "" }); //$NON-NLS-1$ else messageText = SINGLE_MESSAGE_SUMMARY_KEYS[maxType]; // XXX: put the messages in the wizard page, instead of the form heading wizardPage.setErrorMessage(createSummary(array)); // scrolledForm.setMessage(messageText, maxType, array); } } 4. Relax the scope of all referenced fields and methods from private to package-private or protected.
No impact yes, minimal no. A change to protected is an API change. I'll reopen to look at this early in 3.4
Could you attach a patch that shows exactly what you thing we should apply please? I am not sure exactly what you want - are all of the changes going into MessageManager or are you looking for a WizardMessageManager too?
to my understanding the snippet proposes a IMessageManager implementation for wizard. The snippet shows what has to be changed in the implementation present for ManagedForm. I used the proposed snippet. I am unfortunately not allowed to contribute code so I'll explain the steps needed, to show you the approach: 1.) I created a WizardFormPage (that extends WizardPage/implements IWizardPage): public abstract class WizardFormPage extends WizardPage { ... public void createControl(final Composite parent) { createManagedForm(parent)); ... } protected ManagedForm createManagedForm(final Composite parent) { ManagedForm managedForm = new WizardPageManagedForm(parent, this); managedForm.setContainer(this); GridData gridData = new GridData(); gridData.grabExcessHorizontalSpace = true; gridData.grabExcessVerticalSpace = true; gridData.verticalAlignment = SWT.FILL; managedForm.getForm().setLayoutData(gridData); return managedForm; } } 2.) created a WizardPageManagedForm (that extends ManagedForm): public class WizardPageManagedForm extends ManagedForm { private MessageManager messageManager; private FormStyleWizardPage wizardPage; public WizardPageManagedForm(Composite parent, IWizardPage wizardPage) { super(parent); m_wizardPage = wizardPage; getForm().getBody().setLayout(new FillLayout()); } @Override public IMessageManager getMessageManager() { ScrolledForm scrolledForm = getForm(); Validate.notNullArg(scrolledForm); if (m_messageManager == null) { m_messageManager = new WizardMessageManager(scrolledForm, wizardPage); } return m_messageManager; } } 3.) created the proposed WizardMessageManager (that implements IMessageManager) The issue here is that most parts of the current MessageManager are not reusable although the changes to its implementation are restricted to a few lines.
Moving to UA - none of this is our code.
There is no plan to implement this. While we continue to fix bugs in UI Forms we are not adding new features.