Bug 286904 - [modeling] Integrate Forms enhanced tooltips support in AbstractEmfFormPage
diff --git a/modeling/plugins/org.eclipse.pde.emfforms/src/org/eclipse/pde/emfforms/internal/validation/RichTooltipHyperlinkAdapter.java b/modeling/plugins/org.eclipse.pde.emfforms/src/org/eclipse/pde/emfforms/internal/validation/RichTooltipHyperlinkAdapter.java
new file mode 100644
index 0000000..55fe8b6
--- /dev/null
+++ b/modeling/plugins/org.eclipse.pde.emfforms/src/org/eclipse/pde/emfforms/internal/validation/RichTooltipHyperlinkAdapter.java
@@ -0,0 +1,226 @@
+/**
+ * Copyright (c) 2009 Anyware Technologies 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:
+ * Anyware Technologies - initial API and implementation
+ *
+ * $Id: AbstractEmfFormPage.java,v 1.7 2009/08/07 11:03:24 bcabe Exp $
+ */
+package org.eclipse.pde.emfforms.internal.validation;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.*;
+import java.util.List;
+import java.util.Map.Entry;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CTabFolder;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.IManagedForm;
+import org.eclipse.ui.forms.IMessage;
+import org.eclipse.ui.forms.events.HyperlinkAdapter;
+import org.eclipse.ui.forms.events.HyperlinkEvent;
+import org.eclipse.ui.forms.widgets.Form;
+import org.eclipse.ui.forms.widgets.FormText;
+
+public class RichTooltipHyperlinkAdapter extends HyperlinkAdapter {
+
+ private static final String INFO = "info";
+ private static final String WARNING = "warning";
+ private static final String ERROR = "error";
+ private static final String OTHER_ERRORS = "Other errors";
+ private IManagedForm _form;
+ private Shell _shell;
+
+ public RichTooltipHyperlinkAdapter(IManagedForm form) {
+ _form = form;
+ }
+
+ public void linkActivated(HyperlinkEvent e) {
+ if (_shell != null) {
+ _shell.dispose();
+ _shell = null;
+ return;
+ }
+
+ String title = e.getLabel();
+ // String details = title;
+ Object href = e.getHref();
+ Point hl = ((Control) e.widget).toDisplay(0, 0);
+ hl.x += 10;
+ hl.y += 20;
+ _shell = new Shell(_form.getForm().getShell(), SWT.ON_TOP | SWT.TOOL);
+ _shell.setImage(getImage(_form.getForm().getMessageType()));
+ _shell.setText(title);
+ GridLayoutFactory.fillDefaults().margins(10, 10).applyTo(_shell);
+ FormText text = _form.getToolkit().createFormText(_shell, true);
+ Label l = new Label(text, SWT.SEPARATOR | SWT.HORIZONTAL);
+ text.setControl("sep", l);
+
+ GridDataFactory.fillDefaults().applyTo(text);
+ if (href instanceof IMessage[]) {
+ Map<String, List<IMessage>> messagesMap = mapMessages((IMessage[]) href, text);
+ configureFormText(_form.getForm().getForm(), text);
+ text.setText(createFormTextContent(messagesMap), true, false);
+ }
+ _shell.setLocation(hl);
+ _form.getToolkit().adapt(_shell);
+ _shell.pack();
+ _shell.open();
+ }
+
+ private void configureFormText(final Form form, FormText text) {
+ text.addHyperlinkListener(new HyperlinkAdapter() {
+ public void linkActivated(HyperlinkEvent e) {
+ String is = (String) e.getHref();
+ try {
+ int hashCode = Integer.parseInt(is);
+ IMessage[] messages = form.getChildrenMessages();
+ IMessage message = null;
+ for (IMessage m : messages) {
+ if (hashCode == m.hashCode()) {
+ message = m;
+ break;
+ }
+ }
+ _shell.dispose();
+ _shell = null;
+ Control c = message.getControl();
+ if (c != null) {
+ // try to find the formpage to activate it...
+ // find CTabItem
+ CTabItem item = findCTabItem(c);
+ item.getParent().setSelection(item);
+ c.setFocus();
+ }
+ } catch (NumberFormatException ex) {
+ }
+ }
+
+ });
+ text.setImage(ERROR, getImage(IMessageProvider.ERROR));
+ text.setImage(WARNING, getImage(IMessageProvider.WARNING));
+ text.setImage(INFO, getImage(IMessageProvider.INFORMATION));
+ }
+
+ private String createFormTextContent(Map<String, List<IMessage>> messagesMap) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+
+ pw.println("<form>");
+ for (Entry<String, List<IMessage>> entry : messagesMap.entrySet()) {
+ if (!entry.getValue().isEmpty()) {
+ if (OTHER_ERRORS.equals(entry.getKey())) {
+ pw.println("<p><control href=\"sep\" fill=\"true\"/></p>");
+ }
+
+ pw.println("<li style=\"image\" value=\"" + entry.getKey() + "\"><b>" + entry.getKey() + "</b></li>");
+ for (IMessage message : entry.getValue()) {
+ pw.print("<li vspace=\"false\" style=\"image\" bindent=\"10\" indent=\"28\" value=\"");
+ switch (message.getMessageType()) {
+ case IMessageProvider.ERROR :
+ pw.print(ERROR);
+ break;
+ case IMessageProvider.WARNING :
+ pw.print(WARNING);
+ break;
+ case IMessageProvider.INFORMATION :
+ pw.print(INFO);
+ break;
+ }
+ pw.print("\"> <a href=\"");
+ pw.print(message.hashCode() + "");
+ pw.print("\">");
+ if (message.getPrefix() != null)
+ pw.print(message.getPrefix());
+ pw.print(message.getMessage());
+ pw.println("</a></li>");
+ }
+ }
+ }
+ pw.println("</form>");
+ pw.flush();
+ // System.out.println(sw.toString());
+ return sw.toString();
+ }
+
+ private Map<String, List<IMessage>> mapMessages(IMessage[] messages, FormText text) {
+ // find the first message which is associated to a control
+ // and then find its CTabFolder...
+ List<String> pagesNames = new ArrayList<String>();
+ for (IMessage msg : messages) {
+ if (msg.getControl() != null) {
+ CTabItem item = findCTabItem(msg.getControl());
+ for (CTabItem it : item.getParent().getItems()) {
+ pagesNames.add(it.getText());
+ if (it.getImage() != null) {
+ text.setImage(it.getText(), it.getImage());
+ }
+ }
+ }
+ }
+
+ Map<String, List<IMessage>> res = new LinkedHashMap<String, List<IMessage>>();
+ for (String s : pagesNames) {
+ res.put(s, new ArrayList<IMessage>());
+ }
+ res.put(OTHER_ERRORS, new ArrayList<IMessage>());
+ for (IMessage msg : messages) {
+ Form container = findFormContainer(msg.getControl());
+ String key = OTHER_ERRORS;
+ if (container != null)
+ key = container.getText();
+
+ res.get(key).add(msg);
+
+ }
+ return res;
+ }
+
+ private Image getImage(int type) {
+ switch (type) {
+ case IMessageProvider.ERROR :
+ return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJS_ERROR_TSK);
+ case IMessageProvider.WARNING :
+ return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJS_WARN_TSK);
+ case IMessageProvider.INFORMATION :
+ return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJS_INFO_TSK);
+ }
+ return null;
+ }
+
+ private static Form findFormContainer(Control control) {
+ if (control == null)
+ return null;
+ if (control instanceof Form)
+ return (Form) control;
+
+ return findFormContainer(control.getParent());
+ }
+
+ private static CTabItem findCTabItem(Control c) {
+ Form container = findFormContainer(c);
+ Composite c1 = container.getParent();
+ CTabFolder c2 = (CTabFolder) c1.getParent();
+
+ for (CTabItem item : c2.getItems()) {
+ if (item.getControl() == c1) {
+ return item;
+ }
+ }
+ return null;
+
+ }
+}