/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.advisor.ui.core; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.action.IAction; import org.eclipse.swt.SWT; import org.eclipse.swt.accessibility.ACC; import org.eclipse.swt.accessibility.Accessible; import org.eclipse.swt.accessibility.AccessibleAdapter; import org.eclipse.swt.accessibility.AccessibleControlAdapter; import org.eclipse.swt.accessibility.AccessibleControlEvent; import org.eclipse.swt.accessibility.AccessibleEvent; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.events.ControlAdapter; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.TraverseEvent; import org.eclipse.swt.events.TraverseListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; 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.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.forms.events.HyperlinkAdapter; import org.eclipse.ui.forms.events.HyperlinkEvent; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.Hyperlink; import org.teiid.designer.advisor.ui.AdvisorUiConstants; import org.teiid.designer.advisor.ui.Messages; /** * */ public class AdvisorFixDialog { private Color backgroundColour = null; private Color foregroundColour = null; // private Color linkColour = null; protected Shell parentShell; protected Shell shell; protected String infopopText; protected FormToolkit toolkit; private static final String FIVE_SPACES = " "; //$NON-NLS-1$ /** * Constructor: * * @param x the x mouse location in the current display * @param y the y mouse location in the current display */ public AdvisorFixDialog( InfoPopAction[] actions, int x, int y, FormToolkit toolkit ) { Display display = Display.getCurrent(); if (display == null) { return; } this.toolkit = toolkit; backgroundColour = display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND); foregroundColour = display.getSystemColor(SWT.COLOR_INFO_FOREGROUND); // linkColour = display.getSystemColor(SWT.COLOR_BLUE); parentShell = display.getActiveShell(); shell = new Shell(parentShell, SWT.NONE); // PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, IHelpUIConstants.F1_SHELL); shell.addListener(SWT.Deactivate, new Listener() { @Override public void handleEvent( Event e ) { close(); } }); shell.addTraverseListener(new TraverseListener() { @Override public void keyTraversed( TraverseEvent e ) { if (e.detail == SWT.TRAVERSE_ESCAPE) { e.doit = true; } } }); shell.addControlListener(new ControlAdapter() { @Override public void controlMoved( ControlEvent e ) { Rectangle clientArea = shell.getClientArea(); shell.redraw(clientArea.x, clientArea.y, clientArea.width, clientArea.height, true); shell.update(); } }); // linkManager.setHyperlinkUnderlineMode(HyperlinkHandler.UNDERLINE_ALWAYS); createContents(shell, actions); shell.pack(); // Correct x and y of the shell if it not contained within the screen int width = shell.getBounds().width; int height = shell.getBounds().height; Rectangle screen = display.getClientArea(); // check lower boundaries // Add 10 pixels... x += 10; x = x >= screen.x ? x : screen.x; y = y >= screen.y ? y : screen.y; // check upper boundaries x = x + width <= screen.width ? x : screen.width - width; y = y + height <= screen.height ? y : screen.height - height; shell.setLocation(x, y); initAccessible(shell); } public synchronized void close() { try { if (shell != null) { shell.close(); if (!shell.isDisposed()) shell.dispose(); shell = null; } } catch (Throwable ex) { } } protected Control createContents( Composite contents, InfoPopAction[] actions ) { initAccessible(contents); contents.setBackground(backgroundColour); GridLayout layout = new GridLayout(); layout.marginHeight = 5; layout.marginWidth = 5; contents.setLayout(layout); contents.setLayoutData(new GridData(GridData.FILL_BOTH)); // create the dialog area and button bar if (actions.length == 0) { createInfoArea(contents, actions.length); } if (actions.length > 0) { Control c = createLinksArea(contents, actions); if (c != null) { // links exist, make them the only focusable controls contents.setTabList(new Control[] {c}); } } return contents; } private Control createInfoArea( Composite parent, int nActions ) { // Create the text field. String styledText; if (nActions == 0) { styledText = Messages.AdvisorFixDialog_Message_NoActions; } else { styledText = Messages.AdvisorFixDialog_Message_AvailableActions; } Description text = new Description(parent, SWT.MULTI | SWT.READ_ONLY); text.addTraverseListener(new TraverseListener() { @Override public void keyTraversed( TraverseEvent e ) { if (e.detail == SWT.TRAVERSE_ESCAPE) { e.doit = true; } } }); text.getCaret().setVisible(false); text.setBackground(backgroundColour); text.setForeground(foregroundColour); text.setFont(parent.getFont()); int linkWidth = getLinksWidth(text); StyledLineWrapper content = new StyledLineWrapper(styledText, text, linkWidth + 70); text.setContent(content); text.setStyleRanges(content.getStyles()); infopopText = text.getText(); initAccessible(text); return text; } /** * Measures the longest label of related links * * @param text * @return */ private int getLinksWidth( Description text ) { int linkWidth = 200; return linkWidth; } private Control createLinksArea( Composite parent, InfoPopAction[] actions ) { // IHelpResource[] relatedTopics = context.getRelatedTopics(); // if (relatedTopics == null) // return null; // Create control Composite composite = new Composite(parent, SWT.NONE); initAccessible(composite); // find out if any actions are TYPE_FIX, and/or TYPE_DO boolean hasFixes = false; boolean hasDos = false; boolean hasOthers = false; for (int i = 0; i < actions.length; i++) { if (!hasFixes && actions[i].getType() == InfoPopAction.TYPE_FIX) { hasFixes = true; } if (!hasDos && actions[i].getType() == InfoPopAction.TYPE_DO) { hasDos = true; } if (!hasOthers && actions[i].getType() == InfoPopAction.TYPE_OTHER) { hasOthers = true; } } composite.setBackground(backgroundColour); GridLayout layout = new GridLayout(); layout.marginHeight = 2; layout.marginWidth = 0; layout.verticalSpacing = 3; layout.horizontalSpacing = 2; layout.numColumns = 3; composite.setLayout(layout); composite.setFont(parent.getFont()); GridData data = new GridData(GridData.FILL_BOTH | GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_CENTER); composite.setLayoutData(data); if (hasFixes) { addActions(composite, actions, InfoPopAction.TYPE_FIX); // Create separator. // Label label = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL); // label.setBackground(backgroundColour); // label.setForeground(foregroundColour); // data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING // | GridData.FILL_HORIZONTAL); // data.horizontalSpan = 3; // label.setLayoutData(data); // for (int i = 0; i < actions.length; i++) { // if (actions[i].getType() == InfoPopAction.TYPE_FIX) { // if (actions[i].getDescription() != null) { // // Add description here // Label desc = new Label(composite, SWT.FILL); // desc.setBackground(backgroundColour); // desc.setForeground(foregroundColour); // desc.setText(actions[i].getDescription()); // GridData gData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING // | GridData.FILL_HORIZONTAL); // gData.horizontalSpan = 3; // desc.setLayoutData(gData); // } // // Indent the action. // Label spacerLabel = new Label(composite, SWT.NONE); // spacerLabel.setText(FIVE_SPACES); // // Label imageLabel = new Label(composite, SWT.NONE); // imageLabel.setBackground(backgroundColour); // imageLabel.setForeground(foregroundColour); // if (actions[i].getImage() != null) { // imageLabel.setImage(actions[i].getImage()); // } // final Hyperlink actionLink = toolkit.createHyperlink(composite, actions[i].getAction().getText(), SWT.WRAP); // toolkit.adapt(actionLink, true, true); // actionLink.setBackground(backgroundColour); // final IAction nextAction = actions[i].getAction(); // actionLink.setToolTipText(actions[i].getDescription()); // actionLink.addHyperlinkListener(new HyperlinkAdapter() { // @Override // public void linkActivated( HyperlinkEvent e ) { // nextAction.run(); // close(); // } // }); // } // } } if (hasDos) { // Create separator. if (hasFixes) { Label label = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL); label.setBackground(backgroundColour); label.setForeground(foregroundColour); data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL); data.horizontalSpan = 3; label.setLayoutData(data); } addActions(composite, actions, InfoPopAction.TYPE_DO); // for (int i = 0; i < actions.length; i++) { // if (actions[i].getType() == InfoPopAction.TYPE_DO) { // if (actions[i].getDescription() != null) { // // Add description here // Label desc = new Label(composite, SWT.FILL); // desc.setBackground(backgroundColour); // desc.setForeground(foregroundColour); // desc.setText(actions[i].getDescription()); // GridData gData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING // | GridData.FILL_HORIZONTAL); // gData.horizontalSpan = 3; // desc.setLayoutData(gData); // } // // Indent the action. // Label spacerLabel = new Label(composite, SWT.NONE); // spacerLabel.setText(FIVE_SPACES); // // Label imageLabel = new Label(composite, SWT.NONE); // imageLabel.setBackground(backgroundColour); // imageLabel.setForeground(foregroundColour); // if (actions[i].getImage() != null) { // // imageLabel.setImage(actions[i].getImage()); // } // final Hyperlink actionLink = toolkit.createHyperlink(composite, actions[i].getAction().getText(), SWT.WRAP); // toolkit.adapt(actionLink, true, true); // actionLink.setBackground(backgroundColour); // final IAction nextAction = actions[i].getAction(); // actionLink.setToolTipText(actions[i].getDescription()); // actionLink.addHyperlinkListener(new HyperlinkAdapter() { // @Override // public void linkActivated( HyperlinkEvent e ) { // nextAction.run(); // close(); // } // }); // } // } } if (hasOthers) { // Create separator. if (hasDos || hasFixes) { Label label = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL); label.setBackground(backgroundColour); label.setForeground(foregroundColour); data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL); data.horizontalSpan = 3; label.setLayoutData(data); } addActions(composite, actions, InfoPopAction.TYPE_OTHER); // for (int i = 0; i < actions.length; i++) { // if (actions[i].getType() == InfoPopAction.TYPE_OTHER) { // if (actions[i].getDescription() != null) { // // Add description here // Label desc = new Label(composite, SWT.FILL); // desc.setBackground(backgroundColour); // desc.setForeground(foregroundColour); // desc.setText(actions[i].getDescription()); // GridData gData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING // | GridData.FILL_HORIZONTAL); // gData.horizontalSpan = 3; // desc.setLayoutData(gData); // } // // Indent the action. // Label spacerLabel = new Label(composite, SWT.NONE); // spacerLabel.setText(FIVE_SPACES); // // Label imageLabel = new Label(composite, SWT.NONE); // imageLabel.setBackground(backgroundColour); // imageLabel.setForeground(foregroundColour); // if (actions[i].getImage() != null) { // // imageLabel.setImage(actions[i].getImage()); // } // final Hyperlink actionLink = toolkit.createHyperlink(composite, actions[i].getAction().getText(), SWT.WRAP); // toolkit.adapt(actionLink, true, true); // actionLink.setBackground(backgroundColour); // final IAction nextAction = actions[i].getAction(); // actionLink.setToolTipText(actions[i].getDescription()); // actionLink.addHyperlinkListener(new HyperlinkAdapter() { // @Override // public void linkActivated( HyperlinkEvent e ) { // nextAction.run(); // close(); // } // }); // } // } } // Create separator. // Label label = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL); // label.setBackground(backgroundColour); // label.setForeground(foregroundColour); // data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING // | GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL); // data.horizontalSpan = 3; // label.setLayoutData(data); // create link to the dynamic help // createDynamicHelpLink(composite); return composite; } private void addActions(Composite parent, InfoPopAction[] actions, int actionType) { for (int i = 0; i < actions.length; i++) { if (actions[i].getType() == actionType) { if (actions[i].getDescription() != null) { // Add description here Label desc = new Label(parent, SWT.FILL); desc.setBackground(backgroundColour); desc.setForeground(foregroundColour); desc.setText(actions[i].getDescription()); GridData gData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL); gData.horizontalSpan = 3; desc.setLayoutData(gData); } // Indent the action. Label spacerLabel = new Label(parent, SWT.NONE); spacerLabel.setText(FIVE_SPACES); Label imageLabel = new Label(parent, SWT.NONE); imageLabel.setBackground(backgroundColour); imageLabel.setForeground(foregroundColour); if (actions[i].getImage() != null) { imageLabel.setImage(actions[i].getImage()); } final Hyperlink actionLink = toolkit.createHyperlink(parent, actions[i].getAction().getText(), SWT.WRAP); toolkit.adapt(actionLink, true, true); actionLink.setBackground(backgroundColour); final IAction nextAction = actions[i].getAction(); actionLink.setToolTipText(actions[i].getDescription()); actionLink.addHyperlinkListener(new HyperlinkAdapter() { @Override public void linkActivated( HyperlinkEvent e ) { nextAction.run(); close(); } }); } } } public synchronized void open() { try { shell.open(); } catch (Throwable e) { AdvisorUiConstants.UTIL.log(IStatus.ERROR, e, "An error occurred when opening context-sensitive help pop-up."); //$NON-NLS-1$ } } // private Image getImage() { // return HelpUIResources.getImage(IHelpUIConstants.IMAGE_FILE_F1TOPIC); // } public boolean isShowing() { return (shell != null && !shell.isDisposed() && shell.isVisible()); } private void initAccessible( final Control control ) { Accessible accessible = control.getAccessible(); accessible.addAccessibleListener(new AccessibleAdapter() { @Override public void getName( AccessibleEvent e ) { e.result = infopopText; } @Override public void getHelp( AccessibleEvent e ) { e.result = control.getToolTipText(); } }); accessible.addAccessibleControlListener(new AccessibleControlAdapter() { @Override public void getChildAtPoint( AccessibleControlEvent e ) { Point pt = control.toControl(new Point(e.x, e.y)); e.childID = (control.getBounds().contains(pt)) ? ACC.CHILDID_MULTIPLE : ACC.CHILDID_NONE; } @Override public void getLocation( AccessibleControlEvent e ) { Rectangle location = control.getBounds(); Point pt = control.toDisplay(new Point(location.x, location.y)); e.x = pt.x; e.y = pt.y; e.width = location.width; e.height = location.height; } @Override public void getChildCount( AccessibleControlEvent e ) { e.detail = 1; } @Override public void getRole( AccessibleControlEvent e ) { e.detail = ACC.ROLE_LABEL; } @Override public void getState( AccessibleControlEvent e ) { e.detail = ACC.STATE_READONLY; } }); } public class Description extends StyledText { /** * @param parent * @param style */ public Description( Composite parent, int style ) { super(parent, style); } @Override public boolean setFocus() { return false; } @Override public boolean isFocusControl() { return false; } } }