1 11 package org.eclipse.help.ui.internal.browser.embedded; 12 import java.net.MalformedURLException ; 13 import java.net.URL ; 14 import java.util.ArrayList ; 15 import java.util.Iterator ; 16 import java.util.Vector ; 17 18 import org.eclipse.core.runtime.FileLocator; 19 import org.eclipse.core.runtime.IProduct; 20 import org.eclipse.core.runtime.Path; 21 import org.eclipse.core.runtime.Platform; 22 import org.eclipse.core.runtime.Preferences; 23 import org.eclipse.help.internal.base.BaseHelpSystem; 24 import org.eclipse.help.internal.base.HelpBasePlugin; 25 import org.eclipse.help.ui.internal.HelpUIPlugin; 26 import org.eclipse.help.ui.internal.Messages; 27 import org.eclipse.jface.resource.ImageDescriptor; 28 import org.eclipse.osgi.util.NLS; 29 import org.eclipse.swt.SWT; 30 import org.eclipse.swt.browser.Browser; 31 import org.eclipse.swt.browser.CloseWindowListener; 32 import org.eclipse.swt.browser.LocationAdapter; 33 import org.eclipse.swt.browser.LocationEvent; 34 import org.eclipse.swt.browser.LocationListener; 35 import org.eclipse.swt.browser.OpenWindowListener; 36 import org.eclipse.swt.browser.ProgressEvent; 37 import org.eclipse.swt.browser.ProgressListener; 38 import org.eclipse.swt.browser.StatusTextEvent; 39 import org.eclipse.swt.browser.StatusTextListener; 40 import org.eclipse.swt.browser.TitleEvent; 41 import org.eclipse.swt.browser.TitleListener; 42 import org.eclipse.swt.browser.VisibilityWindowListener; 43 import org.eclipse.swt.browser.WindowEvent; 44 import org.eclipse.swt.events.ControlEvent; 45 import org.eclipse.swt.events.ControlListener; 46 import org.eclipse.swt.events.DisposeEvent; 47 import org.eclipse.swt.events.DisposeListener; 48 import org.eclipse.swt.graphics.Image; 49 import org.eclipse.swt.graphics.Point; 50 import org.eclipse.swt.graphics.Rectangle; 51 import org.eclipse.swt.layout.GridData; 52 import org.eclipse.swt.layout.GridLayout; 53 import org.eclipse.swt.widgets.Composite; 54 import org.eclipse.swt.widgets.Label; 55 import org.eclipse.swt.widgets.ProgressBar; 56 import org.eclipse.swt.widgets.Shell; 57 import org.osgi.framework.Bundle; 58 61 public class EmbeddedBrowser { 62 private static final String BROWSER_X = "browser.x"; private static final String BROWSER_Y = "browser.y"; private static final String BROWSER_WIDTH = "browser.w"; private static final String BROWSER_HEIGTH = "browser.h"; private static final String BROWSER_MAXIMIZED = "browser.maximized"; private Preferences store; 68 private static String initialTitle = getWindowTitle(); 69 private Shell shell; 70 private Browser browser; 71 private Browser externalBrowser; 72 private Composite statusBar; 73 private Label statusBarText; 74 private Label statusBarSeparator; 75 private ProgressBar statusBarProgress; 76 private String statusText; 77 private int x, y, w, h; 78 private long modalRequestTime = 0; 79 private Vector closeListeners = new Vector (1); 80 83 public EmbeddedBrowser() { 84 store = HelpUIPlugin.getDefault().getPluginPreferences(); 85 int style = SWT.SHELL_TRIM; 86 if (BaseHelpSystem.isRTL()) 87 style |= SWT.RIGHT_TO_LEFT; 88 else 89 style |= SWT.LEFT_TO_RIGHT; 90 shell = new Shell(style); 91 initializeShell(shell); 92 shell.addControlListener(new ControlListener() { 93 public void controlMoved(ControlEvent e) { 94 if (!shell.getMaximized()) { 95 Point location = shell.getLocation(); 96 x = location.x; 97 y = location.y; 98 } 99 } 100 public void controlResized(ControlEvent e) { 101 if (!shell.getMaximized()) { 102 Point size = shell.getSize(); 103 w = size.x; 104 h = size.y; 105 } 106 } 107 }); 108 shell.addDisposeListener(new DisposeListener() { 109 public void widgetDisposed(DisposeEvent e) { 110 store.setValue(BROWSER_X, Integer.toString(x)); 112 store.setValue(BROWSER_Y, Integer.toString(y)); 113 store.setValue(BROWSER_WIDTH, Integer.toString(w)); 114 store.setValue(BROWSER_HEIGTH, Integer.toString(h)); 115 store.setValue(BROWSER_MAXIMIZED, (new Boolean (shell 116 .getMaximized()).toString())); 117 notifyCloseListners(); 118 } 119 }); 120 browser = new Browser(shell, SWT.NONE); 121 browser.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 122 initialize(browser); 123 124 createStatusBar(shell); 125 initializeStatusBar(browser); 126 127 x = store.getInt(BROWSER_X); 129 y = store.getInt(BROWSER_Y); 130 w = store.getInt(BROWSER_WIDTH); 131 h = store.getInt(BROWSER_HEIGTH); 132 if (w == 0 || h == 0) { 133 w = 1024; 135 h = 768; 136 x = shell.getLocation().x; 137 y = shell.getLocation().y; 138 } 139 setSafeBounds(shell, x, y, w, h); 140 if (store.getBoolean(BROWSER_MAXIMIZED)) 141 shell.setMaximized(true); 142 shell.addControlListener(new ControlListener() { 143 public void controlMoved(ControlEvent e) { 144 if (!shell.getMaximized()) { 145 Point location = shell.getLocation(); 146 x = location.x; 147 y = location.y; 148 } 149 } 150 public void controlResized(ControlEvent e) { 151 if (!shell.getMaximized()) { 152 Point size = shell.getSize(); 153 w = size.x; 154 h = size.y; 155 } 156 } 157 }); 158 159 shell.open(); 161 163 browser.addLocationListener(new LocationListener() { 164 public void changing(LocationEvent e) { 165 modalRequestTime = 0; 167 if (e.location != null 168 && e.location.startsWith("javascript://needModal")) { modalRequestTime = System.currentTimeMillis(); 170 } 171 if (!e.doit && e.location != null 172 && e.location.startsWith("https://")) { try { 174 BaseHelpSystem.getHelpBrowser(true).displayURL( 175 e.location); 176 } catch (Exception exc) { 177 } 178 } 179 } 180 public void changed(LocationEvent e) { 181 } 182 }); 183 } 184 192 public EmbeddedBrowser(WindowEvent event, Shell parent) { 193 if (parent == null){ 194 int style = SWT.SHELL_TRIM; 195 if (BaseHelpSystem.isRTL()) 196 style |= SWT.RIGHT_TO_LEFT; 197 else 198 style |= SWT.LEFT_TO_RIGHT; 199 shell = new Shell(style); 200 } else 201 shell = new Shell(parent, SWT.PRIMARY_MODAL | SWT.DIALOG_TRIM); 202 initializeShell(shell); 203 Browser browser = new Browser(shell, SWT.NONE); 204 browser.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 205 206 initialize(browser); 207 event.browser = browser; 208 209 browser.addLocationListener(new LocationListener() { 210 public void changing(LocationEvent e) { 211 modalRequestTime = 0; 213 if (e.location != null 214 && e.location.startsWith("javascript://needModal")) { modalRequestTime = System.currentTimeMillis(); 216 } 217 } 218 public void changed(LocationEvent e) { 219 } 220 }); 221 } 222 private static void initializeShell(Shell s) { 223 s.setText(initialTitle); 224 Image[] shellImages = createImages(); 225 if (shellImages != null) 226 s.setImages(shellImages); 227 GridLayout layout = new GridLayout(); 228 layout.marginWidth = 0; 229 layout.marginHeight = 0; 230 layout.verticalSpacing = 0; 231 layout.horizontalSpacing = 0; 232 s.setLayout(layout); 233 } 234 private void initialize(Browser browser) { 235 browser.addOpenWindowListener(new OpenWindowListener() { 236 public void open(WindowEvent event) { 237 if (System.currentTimeMillis() - modalRequestTime <= 1000) { 238 new EmbeddedBrowser(event, shell); 239 } 240 else if (event.required) { 241 new EmbeddedBrowser(event, null); 242 } 243 else { 244 displayURLExternal(event); 245 } 246 } 247 }); 248 browser.addVisibilityWindowListener(new VisibilityWindowListener() { 249 public void hide(WindowEvent event) { 250 Browser browser = (Browser) event.widget; 251 Shell shell = browser.getShell(); 252 shell.setVisible(false); 253 } 254 public void show(WindowEvent event) { 255 Browser browser = (Browser) event.widget; 256 Shell shell = browser.getShell(); 257 if (event.location != null) 258 shell.setLocation(event.location); 259 if (event.size != null) { 260 Point size = event.size; 261 shell.setSize(shell.computeSize(size.x, size.y)); 262 } 263 shell.open(); 264 } 265 }); 266 browser.addCloseWindowListener(new CloseWindowListener() { 267 public void close(WindowEvent event) { 268 Browser browser = (Browser) event.widget; 269 Shell shell = browser.getShell(); 270 shell.close(); 271 } 272 }); 273 browser.addTitleListener(new TitleListener() { 274 279 public void changed(TitleEvent event) { 280 if (event.title != null && event.title.length() > 0) { 281 Browser browser = (Browser) event.widget; 282 Shell shell = browser.getShell(); 283 shell.setText(event.title); 284 } 285 } 286 }); 287 browser.addLocationListener(new LocationListener() { 288 public void changing(LocationEvent e) { 289 if (!e.doit && e.location != null 290 && e.location.startsWith("https://")) { try { 292 BaseHelpSystem.getHelpBrowser(true).displayURL( 293 e.location); 294 } catch (Exception exc) { 295 } 296 } 297 } 298 299 public void changed(LocationEvent e) { 300 } 301 }); 302 } 303 304 private void initializeStatusBar(Browser browser) { 305 browser.addStatusTextListener(new StatusTextListener() { 306 public void changed(StatusTextEvent event) { 307 if (!event.text.equals(statusText)) { 308 statusText = event.text; 309 statusBarText.setText(statusText); 310 } 311 } 312 }); 313 browser.addProgressListener(new ProgressListener() { 314 public void changed(ProgressEvent event) { 315 if (event.total > 0) { 316 statusBarProgress.setMaximum(event.total); 317 statusBarProgress.setSelection(Math.min(event.current, event.total)); 318 statusBarSeparator.setVisible(true); 319 statusBarProgress.setVisible(true); 320 } 321 } 322 public void completed(ProgressEvent event) { 323 statusBarSeparator.setVisible(false); 324 statusBarProgress.setVisible(false); 325 } 326 }); 327 } 328 329 private void createStatusBar(Composite parent) { 330 statusBar = new Composite(parent, SWT.NONE); 331 statusBar.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 332 GridLayout layout = new GridLayout(3, false); 333 layout.marginWidth = 0; 334 layout.marginHeight = 0; 335 layout.marginTop = 0; 336 layout.marginLeft = 5; 337 layout.marginRight = 5; 338 layout.marginBottom = 5; 339 statusBar.setLayout(layout); 340 statusBarText = new Label(statusBar, SWT.NONE); 341 statusBarText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); 342 statusBarSeparator = new Label(statusBar, SWT.SEPARATOR | SWT.VERTICAL); 343 statusBarSeparator.setVisible(false); 344 statusBarProgress = new ProgressBar(statusBar, SWT.HORIZONTAL); 345 GridData data = new GridData(SWT.FILL, SWT.CENTER, false, false); 346 data.widthHint = 100; 347 statusBarProgress.setLayoutData(data); 348 statusBarProgress.setVisible(false); 349 statusBarProgress.setMinimum(0); 350 351 355 data = new GridData(SWT.FILL, SWT.CENTER, false, false); 356 data.heightHint = Math.max(statusBarText.computeSize(SWT.DEFAULT, SWT.DEFAULT).y, statusBarProgress.computeSize(SWT.DEFAULT, SWT.DEFAULT).y); 357 statusBarSeparator.setLayoutData(data); 358 } 359 360 public void displayUrl(String url) { 361 browser.setUrl(url); 362 shell.setMinimized(false); 363 shell.forceActive(); 364 } 365 private void displayURLExternal(WindowEvent e) { 366 if (externalBrowser == null) { 367 final Shell externalShell = new Shell(shell, SWT.NONE); 368 externalBrowser = new Browser(externalShell, SWT.NONE); 369 externalBrowser.addLocationListener(new LocationAdapter() { 370 public void changing(final LocationEvent e) { 371 e.doit = false; 372 try { 373 BaseHelpSystem.getHelpBrowser(true).displayURL(e.location); 374 } 375 catch (Throwable t) { 376 String msg = "Error opening external Web browser"; HelpUIPlugin.logError(msg, t); 378 } 379 } 380 }); 381 } 382 e.browser = externalBrowser; 383 } 384 public boolean isDisposed() { 385 return shell.isDisposed(); 386 } 387 private static String getWindowTitle() { 388 if ("true".equalsIgnoreCase(HelpBasePlugin.getDefault() .getPluginPreferences().getString("windowTitlePrefix"))) { return NLS.bind(Messages.browserTitle, BaseHelpSystem 391 .getProductName()); 392 } 393 return BaseHelpSystem.getProductName(); 394 } 395 398 private static Image[] createImages() { 399 String [] productImageURLs = getProductImageURLs(); 400 if (productImageURLs != null) { 401 ArrayList shellImgs = new ArrayList (); 402 for (int i = 0; i < productImageURLs.length; i++) { 403 if ("".equals(productImageURLs[i])) { continue; 405 } 406 URL imageURL = null; 407 try { 408 imageURL = new URL (productImageURLs[i]); 409 } catch (MalformedURLException mue) { 410 IProduct product = Platform.getProduct(); 412 if (product != null) { 413 Bundle productBundle = product.getDefiningBundle(); 414 if (productBundle != null) { 415 imageURL = FileLocator.find(productBundle, new Path( 416 productImageURLs[i]), null); 417 } 418 } 419 } 420 Image image = null; 421 if (imageURL != null) { 422 image = ImageDescriptor.createFromURL(imageURL) 423 .createImage(); 424 } 425 if (image != null) { 426 shellImgs.add(image); 427 } 428 } 429 return (Image[]) shellImgs.toArray(new Image[shellImgs.size()]); 430 } 431 return new Image[0]; 432 } 433 438 private static String [] getProductImageURLs() { 439 IProduct product = Platform.getProduct(); 440 if (product != null) { 441 String url = product.getProperty("windowImages"); if (url != null && url.length() > 0) { 443 return url.split(",\\s*"); } 445 url = product.getProperty("windowImage"); if (url != null && url.length() > 0) { 447 return new String []{url}; 448 } 449 } 450 return null; 451 } 452 455 public void close() { 456 if (!shell.isDisposed()) 457 shell.dispose(); 458 } 459 private static void setSafeBounds(Shell s, int x, int y, int width, 460 int height) { 461 Rectangle clientArea = s.getDisplay().getClientArea(); 462 width = Math.min(clientArea.width, width); 463 height = Math.min(clientArea.height, height); 464 x = Math.min(x + width, clientArea.x + clientArea.width) - width; 465 y = Math.min(y + height, clientArea.y + clientArea.height) - height; 466 x = Math.max(x, clientArea.x); 467 y = Math.max(y, clientArea.y); 468 s.setBounds(x, y, width, height); 469 } 470 public void setLocation(int x, int y) { 471 shell.setLocation(x, y); 472 } 473 public void setSize(int width, int height) { 474 shell.setSize(w, h); 475 } 476 private void notifyCloseListners() { 477 for (Iterator it = closeListeners.iterator(); it.hasNext();) { 478 IBrowserCloseListener listener = (IBrowserCloseListener) it.next(); 479 listener.browserClosed(); 480 } 481 } 482 483 public void addCloseListener(IBrowserCloseListener listener) { 484 if (!closeListeners.contains(listener)) { 485 closeListeners.add(listener); 486 } 487 } 488 489 public void removeCloseListener(IBrowserCloseListener listener) { 490 closeListeners.remove(listener); 491 } 492 } 493 | Popular Tags |