1765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye/******************************************************************************* 2765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Copyright (c) 2011 Google, Inc. 3765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * All rights reserved. This program and the accompanying materials 4765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * are made available under the terms of the Eclipse Public License v1.0 5765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * which accompanies this distribution, and is available at 6765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * http://www.eclipse.org/legal/epl-v10.html 7765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * 8765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Contributors: 9765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Google, Inc. - initial API and implementation 10765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye *******************************************************************************/ 11765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyepackage org.eclipse.wb.internal.core.model.property.table; 12765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 13765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport com.google.common.base.Charsets; 14765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport com.google.common.base.Joiner; 15765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 16765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.SWT; 17765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.browser.Browser; 18765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.browser.LocationAdapter; 19765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.browser.LocationEvent; 20765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.browser.ProgressAdapter; 21765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.browser.ProgressEvent; 22765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.graphics.Color; 23765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.graphics.Point; 24765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.widgets.Composite; 25765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.widgets.Control; 26765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.widgets.Event; 27765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.widgets.Label; 28765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.widgets.Listener; 29765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.widgets.Shell; 30765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.ui.PlatformUI; 31765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.ui.browser.IWebBrowser; 32765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.ui.browser.IWorkbenchBrowserSupport; 33765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.wb.draw2d.IColorConstants; 34765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.wb.internal.core.DesignerPlugin; 35765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.wb.internal.core.EnvironmentUtils; 36765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.wb.internal.core.utils.reflect.ReflectionUtils; 37765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.wb.internal.core.utils.ui.GridDataFactory; 38765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.wb.internal.core.utils.ui.PixelConverter; 39765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 40765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport java.io.StringReader; 41765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport java.net.URL; 42765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport java.text.MessageFormat; 43765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 44765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye/** 45765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Helper for displaying HTML tooltips. 46765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * 47765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @author scheglov_ke 48765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @coverage core.model.property.table 49765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 50765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyepublic final class HtmlTooltipHelper { 51765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public static Control createTooltipControl(Composite parent, String header, String details) { 52765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return createTooltipControl(parent, header, details, 0); 53765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 54765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 55765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public static Control createTooltipControl(Composite parent, 56765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye String header, 57765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye String details, 58765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int heightLimit) { 59765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // prepare Control 60765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Control control; 61765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye try { 62765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye String html = "<table cellspacing=2 cellpadding=0 border=0 margins=0 id=_wbp_tooltip_body>"; 63765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (header != null) { 64765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye html += "<tr align=center><td><b>" + header + "</b></td></tr>"; 65765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 66765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye html += "<tr><td align=justify>" + details + "</td></tr>"; 67765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye html += "</table>"; 68765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye control = createTooltipControl_Browser(parent, html, heightLimit); 69765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } catch (Throwable e) { 70765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye control = createTooltipControl_Label(parent, details); 71765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 72765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // set listeners 73765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye { 74765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Listener listener = new Listener() { 75765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye @Override 76765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void handleEvent(Event event) { 77765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Control tooltipControl = (Control) event.widget; 78765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye hideTooltip(tooltipControl); 79765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 80765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye }; 81765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye control.addListener(SWT.MouseExit, listener); 82765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 83765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // done 84765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return control; 85765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 86765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 87765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 88765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Creates {@link Browser} for displaying tooltip. 89765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 90765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static Control createTooltipControl_Browser(Composite parent, 91765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye String html, 92765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye final int heightLimitChars) { 93765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // prepare styles 94765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye String styles; 95765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye try { 96765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye styles = DesignerPlugin.readFile(PropertyTable.class.getResourceAsStream("Tooltip.css"), 97765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Charsets.US_ASCII); 98765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (styles == null) { 99765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye styles = ""; 100765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 101765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } catch (Throwable e) { 102765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye styles = ""; 103765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 104765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // prepare HTML with styles and tags 105765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye String wrappedHtml; 106765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye { 107765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye String bodyAttributes = 108765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye MessageFormat.format( 109765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye "text=''{0}'' bgcolor=''{1}''", 110765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye getColorWebString(IColorConstants.tooltipForeground), 111765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye getColorWebString(IColorConstants.tooltipBackground)); 112765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye String closeElement = 113765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye EnvironmentUtils.IS_LINUX 114765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye ? " <a href='' style='position:absolute;right:1em;' id=_wbp_close>Close</a>" 115765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye : ""; 116765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye wrappedHtml = 117765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /*CodeUtils.*/getSource( 118765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye "<html>", 119765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye " <style CHARSET='ISO-8859-1' TYPE='text/css'>", 120765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye styles, 121765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye " </style>", 122765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye " <body " + bodyAttributes + ">", 123765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye closeElement, 124765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye html, 125765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye " </body>", 126765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye "</html>"); 127765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 128765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // prepare Browser 129765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye final Browser browser = new Browser(parent, SWT.NONE); 130765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye browser.setText(wrappedHtml); 131765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // open URLs in new window 132765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye browser.addLocationListener(new LocationAdapter() { 133765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye @Override 134765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void changing(LocationEvent event) { 135765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye event.doit = false; 136765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye hideTooltip((Browser) event.widget); 137765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (!"about:blank".equals(event.location)) { 138765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye try { 139765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye IWorkbenchBrowserSupport support = PlatformUI.getWorkbench().getBrowserSupport(); 140765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye IWebBrowser browserSupport = support.createBrowser("wbp.browser"); 141765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye browserSupport.openURL(new URL(event.location)); 142765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } catch (Throwable e) { 143765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye DesignerPlugin.log(e); 144765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 145765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 146765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 147765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye }); 148765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // set size 149765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye { 150765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int textLength = getTextLength(html); 151765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // horizontal hint 152765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int hintH = 50; 153765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (textLength < 100) { 154765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye hintH = 40; 155765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 156765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // vertical hint 157765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int hintV = textLength / hintH + 3; 158765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye hintV = Math.min(hintV, 8); 159765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // do set 160765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye GridDataFactory.create(browser).hintC(hintH, hintV); 161765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 162765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // tweak size after rendering HTML 163765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye browser.addProgressListener(new ProgressAdapter() { 164765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye @Override 165765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void completed(ProgressEvent event) { 166765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye browser.removeProgressListener(this); 167765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye tweakBrowserSize(browser, heightLimitChars); 168765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye browser.getShell().setVisible(true); 169765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 170765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye }); 171765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // done 172765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return browser; 173765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 174765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 175765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static void tweakBrowserSize(Browser browser, int heightLimitChars) { 176765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye GridDataFactory.create(browser).grab().fill(); 177765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // limit height 178765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (heightLimitChars != 0) { 179765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye PixelConverter pixelConverter = new PixelConverter(browser); 180765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int maxHeight = pixelConverter.convertHeightInCharsToPixels(heightLimitChars); 181765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye expandShellToShowFullPage_Height(browser, maxHeight); 182765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 183765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // if no limit, then show all, so make as tall as required 184765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (heightLimitChars == 0) { 185765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye expandShellToShowFullPage_Height(browser, Integer.MAX_VALUE); 186765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 187765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 188765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 189765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static void expandShellToShowFullPage_Height(Browser browser, int maxHeight) { 190765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye try { 191765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Shell shell = browser.getShell(); 192765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // calculate required 193765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int contentHeight; 194765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye { 195765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye getContentOffsetHeight(browser); 196765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye contentHeight = getContentScrollHeight(browser); 197765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 198765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // apply height 199765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int useHeight = Math.min(contentHeight + ((EnvironmentUtils.IS_LINUX) ? 2 : 10), maxHeight); 200765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye shell.setSize(shell.getSize().x, useHeight); 201765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // trim height to content 202765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye { 203765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int offsetHeight = getBodyOffsetHeight(browser); 204765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int scrollHeight = getBodyScrollHeight(browser); 205765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int delta = scrollHeight - offsetHeight; 206765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (delta != 0 && delta < 10) { 207765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Point size = shell.getSize(); 208765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye shell.setSize(size.x, size.y + delta + 1); 209765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 210765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 211765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // trim width to content 212765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye { 213765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int offsetWidth = getContentOffsetWidth(browser); 214765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye { 215765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Point size = shell.getSize(); 216765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye shell.setSize(offsetWidth + ((EnvironmentUtils.IS_MAC) ? 6 : 10), size.y); 217765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 218765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 219765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // hide 'Close' if too narrow 220765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (EnvironmentUtils.IS_LINUX) { 221765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (shell.getSize().y < 30) { 222765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye hideCloseElement(browser); 223765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 224765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 225765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } catch (Throwable e) { 226765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 227765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 228765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 229765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static int getContentOffsetWidth(Browser browser) throws Exception { 230765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return evaluateScriptInt( 231765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye browser, 232765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye "return document.getElementById('_wbp_tooltip_body').offsetWidth;"); 233765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 234765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 235765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static int getContentOffsetHeight(Browser browser) throws Exception { 236765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return evaluateScriptInt( 237765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye browser, 238765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye "return document.getElementById('_wbp_tooltip_body').offsetHeight;"); 239765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 240765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 241765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static int getContentScrollHeight(Browser browser) throws Exception { 242765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return evaluateScriptInt( 243765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye browser, 244765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye "return document.getElementById('_wbp_tooltip_body').scrollHeight;"); 245765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 246765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 247765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static int getBodyOffsetHeight(Browser browser) throws Exception { 248765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return evaluateScriptInt(browser, "return document.body.offsetHeight;"); 249765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 250765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 251765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static int getBodyScrollHeight(Browser browser) throws Exception { 252765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return evaluateScriptInt(browser, "return document.body.scrollHeight;"); 253765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 254765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 255765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static int evaluateScriptInt(Browser browser, String script) throws Exception { 256765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Object o = ReflectionUtils.invokeMethod(browser, "evaluate(java.lang.String)", script); 257765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return ((Number) o).intValue(); 258765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 259765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 260765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static void hideCloseElement(Browser browser) throws Exception { 261765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye String script = "document.getElementById('_wbp_close').style.display = 'none'"; 262765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye ReflectionUtils.invokeMethod(browser, "evaluate(java.lang.String)", script); 263765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 264765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 265765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 266765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return the length of text in given HTML. Uses internal class, so may fail, in this case 267765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * returns length on HTML. 268765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 269765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static int getTextLength(String html) { 270765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye StringReader htmlStringReader = new StringReader(html); 271765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye try { 272765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye ClassLoader classLoader = PropertyTable.class.getClassLoader(); 273765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Class<?> readerClass = 274765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye classLoader.loadClass("org.eclipse.jface.internal.text.html.HTML2TextReader"); 275765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Object reader = readerClass.getConstructors()[0].newInstance(htmlStringReader, null); 276765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye String text = (String) ReflectionUtils.invokeMethod(reader, "getString()"); 277765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return text.length(); 278765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } catch (Throwable e) { 279765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return html.length(); 280765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 281765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 282765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 283765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 284765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Returns a string representation of {@link Color} suitable for web pages. 285765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * 286765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @param color 287765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * the {@link Color} instance, not <code>null</code>. 288765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return a string representation of {@link Color} suitable for web pages. 289765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 290765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static String getColorWebString(final Color color) { 291765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye String colorString = "#" + Integer.toHexString(color.getRed()); 292765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye colorString += Integer.toHexString(color.getGreen()); 293765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye colorString += Integer.toHexString(color.getBlue()); 294765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return colorString; 295765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 296765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 297765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 298765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Creates {@link Label} if {@link Browser} can not be used. 299765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 300765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static Control createTooltipControl_Label(Composite parent, String html) { 301765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // prepare Label 302765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye final Label label = new Label(parent, SWT.WRAP); 303765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye label.setText(html); 304765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // set size 305765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int requiredWidth = label.computeSize(SWT.DEFAULT, SWT.DEFAULT).x; 306765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye GridDataFactory.create(label).hintHC(50).hintHMin(requiredWidth); 307765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // copy colors 308765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye label.setForeground(parent.getForeground()); 309765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye label.setBackground(parent.getBackground()); 310765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // done 311765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye parent.getDisplay().asyncExec(new Runnable() { 312765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye @Override 313765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void run() { 314765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Shell shell = label.getShell(); 315765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye shell.setVisible(true); 316765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 317765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye }); 318765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return label; 319765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 320765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 321765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static void hideTooltip(Control tooltip) { 322765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye tooltip.getShell().dispose(); 323765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 324765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 325765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Copied from CodeUtils.java: CodeUtils.getSource() 326765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 327765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return the source as single {@link String}, lines joined using "\n". 328765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 329765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public static String getSource(String... lines) { 330765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return Joiner.on('\n').join(lines); 331765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 332765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye} 333