1 19 20 package com.sslexplorer.agent.client.gui.swt; 21 22 import java.io.IOException ; 23 import java.io.InputStream ; 24 import java.text.MessageFormat ; 25 import java.util.ArrayList ; 26 import java.util.Hashtable ; 27 import java.util.List ; 28 29 import org.eclipse.swt.SWT; 30 import org.eclipse.swt.events.SelectionEvent; 31 import org.eclipse.swt.events.SelectionListener; 32 import org.eclipse.swt.graphics.Image; 33 import org.eclipse.swt.graphics.Point; 34 import org.eclipse.swt.layout.FillLayout; 35 import org.eclipse.swt.layout.GridData; 36 import org.eclipse.swt.layout.GridLayout; 37 import org.eclipse.swt.widgets.Composite; 38 import org.eclipse.swt.widgets.Display; 39 import org.eclipse.swt.widgets.Event; 40 import org.eclipse.swt.widgets.Label; 41 import org.eclipse.swt.widgets.Listener; 42 import org.eclipse.swt.widgets.Menu; 43 import org.eclipse.swt.widgets.MenuItem; 44 import org.eclipse.swt.widgets.MessageBox; 45 import org.eclipse.swt.widgets.Shell; 46 import org.eclipse.swt.widgets.Tray; 47 import org.eclipse.swt.widgets.TrayItem; 48 49 import com.maverick.http.HttpAuthenticator; 50 import com.sslexplorer.agent.client.ActionCallback; 51 import com.sslexplorer.agent.client.Agent; 52 import com.sslexplorer.agent.client.AgentAction; 53 import com.sslexplorer.agent.client.AgentClientGUI; 54 import com.sslexplorer.agent.client.Console; 55 import com.sslexplorer.agent.client.PortMonitor; 56 import com.sslexplorer.agent.client.TaskProgress; 57 import com.sslexplorer.agent.client.util.BrowserLauncher; 58 59 65 public class SWTSystemTrayGUI implements AgentClientGUI { 66 67 static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(SWTSystemTrayGUI.class); 69 71 final int IDLE_ICON = 0; 72 final int TX_ICON = 1; 73 final int RX_ICON = 2; 74 final int TXRX_ICON = 3; 75 final int DISCONNECTED_ICON = 4; 76 77 80 public final static int DEFAULT_TIMEOUT = 10000; 81 82 84 private Image[] icons; 85 private Tray tray; 86 private TrayItem trayItem; 87 private Display display; 88 private Agent agent; 89 private Menu popupMenu; 90 private Shell shell; 91 private Object initLock = new Object () { 92 }; 93 private SWTBalloonWindow balloon; 94 private Label messageLabel; 95 private PortMonitor portMonitor; 96 private PopupTimer popupTimer; 97 private Console console; 98 private int menuIdx = 0; 99 100 private Hashtable menuLookup = new Hashtable (); 101 private Hashtable menuItemLookup = new Hashtable (); 102 103 108 public void init(Agent agent) { 109 this.agent = agent; 110 Thread t = new Thread () { 111 public void run() { 112 doInit(); 113 eventLoop(); 114 } 115 }; 116 t.start(); 117 synchronized (initLock) { 118 try { 119 initLock.wait(); 120 } catch (InterruptedException e) { 121 } 122 } 123 124 } 125 126 public Menu getMenu() { 127 return popupMenu; 128 } 129 130 public Agent getAgent() { 131 return agent; 132 } 133 134 public Display getDisplay() { 135 return display; 136 } 137 138 public Shell getShell() { 139 return shell; 140 } 141 142 protected void doInit() { 143 display = new Display(); 145 shell = new Shell(display); 146 147 icons = new Image[5]; 149 icons[IDLE_ICON] = loadImage(SWTSystemTrayGUI.class, "/images/tray-idle.gif"); icons[TX_ICON] = loadImage(SWTSystemTrayGUI.class, "/images/tray-tx.gif"); icons[RX_ICON] = loadImage(SWTSystemTrayGUI.class, "/images/tray-rx.gif"); icons[TXRX_ICON] = loadImage(SWTSystemTrayGUI.class, "/images/tray-txrx.gif"); icons[DISCONNECTED_ICON] = loadImage(SWTSystemTrayGUI.class, "/images/tray-disconnecting.gif"); 155 popupMenu = new Menu(shell, SWT.POP_UP); 157 158 MenuItem open = new MenuItem(popupMenu, SWT.PUSH); 159 open.setText(Messages.getString("GUI.menu.openBrowser")); open.addSelectionListener(new SelectionListener() { 161 public void widgetDefaultSelected(SelectionEvent e) { 162 } 163 164 public void widgetSelected(SelectionEvent e) { 165 openBrowser(null); 166 } 167 }); 168 169 MenuItem console = new MenuItem(popupMenu, SWT.PUSH); 171 console.setText(Messages.getString("GUI.menu.debugConsole")); console.addSelectionListener(new SelectionListener() { 173 public void widgetDefaultSelected(SelectionEvent e) { 174 } 175 176 public void widgetSelected(SelectionEvent e) { 177 getConsole().show(); 178 } 179 }); 180 MenuItem ports = new MenuItem(popupMenu, SWT.PUSH); 182 ports.setText(Messages.getString("GUI.menu.tunnelMonitor")); ports.addSelectionListener(new SelectionListener() { 184 public void widgetDefaultSelected(SelectionEvent e) { 185 } 186 187 public void widgetSelected(SelectionEvent e) { 188 getPortMonitor().setVisible(!getPortMonitor().isVisible()); 189 } 190 }); 191 MenuItem about = new MenuItem(popupMenu, SWT.PUSH); 192 about.setText(Messages.getString("GUI.menu.about")); about.addSelectionListener(new SelectionListener() { 194 public void widgetDefaultSelected(SelectionEvent e) { 195 } 196 197 public void widgetSelected(SelectionEvent e) { 198 about(); 199 } 200 }); 201 202 new MenuItem(popupMenu, SWT.SEPARATOR); 204 MenuItem exit = new MenuItem(popupMenu, SWT.PUSH); 205 exit.setText(Messages.getString("GUI.menu.exit")); exit.addSelectionListener(new SelectionListener() { 207 public void widgetDefaultSelected(SelectionEvent e) { 208 } 209 210 public void widgetSelected(SelectionEvent e) { 211 exit(); 212 } 213 }); 214 215 tray = display.getSystemTray(); 217 if (tray == null) { 218 log.error("The system tray is not available"); 220 } else { 222 trayItem = new TrayItem(tray, SWT.NONE); 224 trayItem.setToolTipText("SSL-Explorer Agent"); 225 trayItem.addListener(SWT.Show, new Listener() { 226 public void handleEvent(Event event) { 227 } 228 }); 229 trayItem.addListener(SWT.Hide, new Listener() { 230 public void handleEvent(Event event) { 231 } 232 }); 233 trayItem.addListener(SWT.Selection, new Listener() { 234 public void handleEvent(Event event) { 235 } 236 }); 237 trayItem.addListener(SWT.DefaultSelection, new Listener() { 238 public void handleEvent(Event event) { 239 } 240 }); 241 trayItem.addListener(SWT.MenuDetect, new Listener() { 242 public void handleEvent(Event event) { 243 popupMenu.setVisible(true); 244 } 245 }); 246 trayItem.setImage(icons[IDLE_ICON]); 247 } 248 } 249 250 void about() { 251 final Image image = loadImage(SWTSystemTrayGUI.class, "/images/frame-agent.png"); 252 SWTAboutDialog about = new SWTAboutDialog(shell, 253 Messages.getString("About.close"), 254 Messages.getString("About.title"), 255 image, 256 MessageFormat.format(Messages.getString("About.message"), new Object [] { agent.getServerVersion() }), 257 Messages.getString("About.description"), 258 Messages.getString("About.copyright"), 259 Messages.getString("About.link")); 260 261 if (agent.getState() != Agent.STATE_DISCONNECTED) { 262 263 Composite shell = about.getAccessory(); 264 265 Composite c = new Composite(shell, 0); 266 GridLayout gridLayout = new GridLayout(); 267 c.setLayout(gridLayout); 268 269 Label host = new Label(c, SWT.WRAP); 270 host.setText(MessageFormat.format(Messages.getString("About.host"), new Object [] { agent.getSSLExplorerHost() })); 271 GridData data = new GridData(); 272 data.horizontalAlignment = GridData.BEGINNING; 273 data.grabExcessHorizontalSpace = true; 274 host.setLayoutData(data); 275 276 Label port = new Label(c, SWT.WRAP); 277 port.setText(MessageFormat.format(Messages.getString("About.port"), 278 new Object [] { String.valueOf(agent.getSSLExplorerPort()) })); 279 data = new GridData(); 280 data.horizontalAlignment = GridData.BEGINNING; 281 data.grabExcessHorizontalSpace = true; 282 port.setLayoutData(data); 283 284 Label username = new Label(c, SWT.WRAP); 285 username.setText(MessageFormat.format(Messages.getString("About.username"), new Object [] { agent.getUsername() })); 286 data = new GridData(); 287 data.horizontalAlignment = GridData.BEGINNING; 288 data.grabExcessHorizontalSpace = true; 289 username.setLayoutData(data); 290 291 Label serverVersion = new Label(c, SWT.WRAP); 292 serverVersion.setText(MessageFormat.format(Messages.getString("About.serverVersion"), 293 new Object [] { agent.getServerVersion() })); 294 data = new GridData(); 295 data.horizontalAlignment = GridData.BEGINNING; 296 data.grabExcessHorizontalSpace = true; 297 serverVersion.setLayoutData(data); 298 299 Label agentVersion = new Label(c, SWT.WRAP); 300 agentVersion.setText(MessageFormat.format(Messages.getString("About.agentVersion"), 301 new Object [] { agent.getClientVersion() })); 302 data = new GridData(); 303 data.horizontalAlignment = GridData.BEGINNING; 304 data.grabExcessHorizontalSpace = true; 305 agentVersion.setLayoutData(data); 306 } 307 308 about.open(); 309 } 310 311 316 public void openBrowser(String path) { 317 try { 318 String browserPath = "https://" + agent.getSSLExplorerHost() + ":" + agent.getSSLExplorerPort() + (path == null ? "" : ("/" + path)); 320 log.info("Opening browser to " + browserPath); 322 BrowserLauncher.openURL(browserPath); 324 } catch (IOException ioe) { 325 log.error(ioe); 327 } 329 } 330 331 void eventLoop() { 332 synchronized (initLock) { 333 initLock.notify(); 334 } 335 while (true) { 336 if (!display.readAndDispatch()) 337 display.sleep(); 338 } 339 } 340 341 346 public void showIdle() { 347 setImage(icons[IDLE_ICON]); 348 } 349 350 355 public void showDisconnected() { 356 setImage(icons[DISCONNECTED_ICON]); 357 } 358 359 364 public void showTx() { 365 setImage(icons[TX_ICON]); 366 } 367 368 373 public void showRx() { 374 setImage(icons[RX_ICON]); 375 } 376 377 382 public void showTxRx() { 383 setImage(icons[TXRX_ICON]); 384 } 385 386 void setImage(final Image image) { 387 display.asyncExec(new Runnable () { 388 public void run() { 389 trayItem.setImage(image); 390 } 391 }); 392 } 393 394 399 public void setInfo(final String info) { 400 display.asyncExec(new Runnable () { 401 public void run() { 402 trayItem.setToolTipText(info); 403 } 404 }); 405 } 406 407 protected Image loadImage(Class clazz, String path) { 408 InputStream stream = clazz.getResourceAsStream(path); 409 return stream == null ? null : new Image(display, stream); 410 } 411 412 public boolean confirm(final int dialogType, final String okText, final String cancelText, final String title, 413 final String message) { 414 final List l = new ArrayList (); 415 display.syncExec(new Runnable () { 416 public void run() { 417 int type = SWT.ICON_QUESTION; 418 if (dialogType == INFORMATION) { 419 type = SWT.ICON_INFORMATION; 420 } else if (dialogType == ERROR) { 421 type = SWT.ICON_ERROR; 422 } else if (dialogType == WARNING) { 423 type = SWT.ICON_WARNING; 424 } 425 MessageBox messageBox = new MessageBox(shell, type | SWT.OK | (cancelText != null ? SWT.CANCEL : 0)); 426 messageBox.setText(title); 427 messageBox.setMessage(message); 428 int buttonID = messageBox.open(); 429 switch (buttonID) { 430 case SWT.OK: 431 l.add(Boolean.TRUE); 432 default: 433 l.add(Boolean.FALSE); 434 } 435 } 436 }); 437 return ((Boolean ) l.get(0)).booleanValue(); 438 } 439 440 447 public boolean error(String okText, String cancelText, String title, String message, Throwable ex) { 448 return confirm(ERROR, okText, cancelText, title, message); 449 } 450 451 456 public synchronized Console getConsole() { 457 if (console == null) { 458 console = new SWTConsoleOutputStream("true".equals(System.getProperty("console.toSysOut", "false")) ? System.out : null, this); } 460 return console; 461 } 462 463 469 public TaskProgress createTaskProgress(String message, String note, long maxValue, boolean allowCancel) { 470 return new SWTProgressDialog(this, (int) maxValue, allowCancel, message, note); 471 } 472 473 479 public void popup(final ActionCallback callback, final String message, final String title, final String imageName, 480 final int timeout) { 481 display.syncExec(new Runnable () { 482 public void run() { 483 484 if (popupTimer != null) { 485 popupTimer.setBalloon(null); 486 } 487 popupTimer = new PopupTimer(); 488 489 if (balloon != null && !balloon.getShell().isDisposed()) { 490 balloon.setVisible(false); 491 } 492 balloon = new SWTBalloonWindow(display, SWT.ON_TOP | SWT.TITLE | SWT.CLOSE); 493 balloon.setAutoLocation(SWT.BOTTOM | SWT.RIGHT); 494 balloon.setLocation(56, 56); 495 balloon.setAnchor(SWT.BOTTOM | SWT.RIGHT); 496 balloon.setAutoAnchor(false); 497 balloon.getContents().setLayout(new FillLayout()); 498 balloon.addListener(SWT.Selection, new Listener() { 499 public void handleEvent(Event event) { 500 log.debug("Balloon selected"); 502 if (callback != null) { 504 callback.actionPerformed(); 505 } 506 balloon.close(); 507 } 508 }); 509 messageLabel = new Label(balloon.getContents(), SWT.WRAP); 510 messageLabel.setForeground(balloon.getShell().getForeground()); 511 messageLabel.setBackground(balloon.getShell().getBackground()); 512 balloon.addSelectionControl(messageLabel); 513 balloon.setText(title); 514 515 messageLabel.setText(message == null ? "<No message supplied>" : message); 517 messageLabel.setSize(messageLabel.computeSize(300, SWT.DEFAULT)); 518 Composite c = balloon.getContents(); 519 Point messageSize = messageLabel.getSize(); 520 Image image = imageName != null ? loadImage(SWTSystemTrayGUI.class, "/images/" + imageName + ".png") : null; 521 if (image != null) { 522 balloon.setImage(image); 523 c.setSize(messageSize.x, messageSize.y); 524 } else { 525 c.setSize(messageSize); 526 } 527 if (!balloon.getShell().getVisible()) { 528 balloon.setVisible(true); 529 } 530 if (timeout != 0) { 531 popupTimer.setBalloon(balloon); 532 display.timerExec(timeout == -1 ? DEFAULT_TIMEOUT : timeout, popupTimer); 533 } 534 } 535 }); 536 } 537 538 public PortMonitor getPortMonitor() { 539 if (portMonitor == null) { 540 createPortMonitor(); 541 } 542 return portMonitor; 543 } 544 545 public boolean promptForCredentials(final boolean proxy, final HttpAuthenticator authenticator) { 546 return ((Boolean ) SWTRunner.syncExec(display, new SWTRunner() { 547 public Object doRun() { 548 return new Boolean (SWTAuthenticationDialog.promptForCredentials(proxy, shell, authenticator, null)); 549 } 550 551 })).booleanValue(); 552 } 553 554 public void dispose() { 555 shell.getDisplay().syncExec(new Runnable () { 556 public void run() { 557 if (tray != null) { 558 trayItem.dispose(); 559 tray.dispose(); 560 } 561 getPortMonitor().dispose(); 562 getConsole().dispose(); 563 } 564 }); 565 } 566 567 public void addMenu(final String name) { 568 569 display.syncExec(new Runnable () { 570 public void run() { 571 if (menuIdx == 0) { 572 new MenuItem(popupMenu, SWT.SEPARATOR, 0); 573 } 574 MenuItem item = new MenuItem(popupMenu, SWT.CASCADE, menuIdx); 575 menuIdx++; 576 item.setText(name); 577 Menu menu = new Menu(popupMenu); 578 item.setMenu(menu); 579 menuLookup.put(name, menu); 580 menuItemLookup.put(name, item); 581 } 582 }); 583 } 584 585 public void removeMenu(final String name) { 586 587 display.syncExec(new Runnable () { 588 public void run() { 589 Menu menu = (Menu)menuLookup.get(name); 590 MenuItem menuItem = (MenuItem)menuItemLookup.get(name); 591 if(menu != null) { 592 menu.dispose(); 593 menuItem.dispose(); 594 menuLookup.remove(name); 595 menuItemLookup.remove(name); 596 } 597 } 598 }); 599 } 600 601 public void clearMenu(final String name) { 602 603 display.syncExec(new Runnable () { 604 public void run() { 605 Menu menu = (Menu)menuLookup.get(name); 606 if(menu != null) { 607 while(menu.getItemCount() > 0) { 608 menu.getItem(0).dispose(); 609 } 610 } 611 } 612 }); 613 } 614 615 public boolean isMenuExists(String name) { 616 return menuLookup.containsKey(name); 617 } 618 619 620 public void addMenuItem(String name, final AgentAction action) { 621 622 log.debug("Adding menu item " + action.getAction() + " to " + name); 624 final Menu parentMenu = name == null ? popupMenu : (Menu) menuLookup.get(name); 626 if (parentMenu == null) { 627 log.error("No parent menu item " + name + " for " + action.getAction()); 629 return; 631 } 632 633 display.syncExec(new Runnable () { 634 public void run() { 635 MenuItem item = new MenuItem(parentMenu, SWT.PUSH); 636 item.setText(action.getAction()); 637 item.addSelectionListener(new SelectionListener() { 638 public void widgetDefaultSelected(SelectionEvent e) { 639 } 640 641 public void widgetSelected(SelectionEvent e) { 642 action.actionPerformed(); 643 } 644 }); 645 } 646 }); 647 } 648 649 public void addMenuSeperator(String name) { 650 651 final Menu parentMenu = name == null ? popupMenu : (Menu) menuLookup.get(name); 652 if (parentMenu == null) 653 return; 654 display.syncExec(new Runnable () { 655 public void run() { 656 new MenuItem(parentMenu, SWT.SEPARATOR); 657 } 658 }); 659 660 } 661 662 protected void createPortMonitor() { 663 display.syncExec(new Runnable () { 664 public void run() { 665 portMonitor = new SWTPortMonitor(SWTSystemTrayGUI.this); 666 } 667 }); 668 } 669 670 protected void exit() { 671 agent.disconnect(); 672 } 673 674 class PopupTimer implements Runnable { 675 676 private SWTBalloonWindow balloon; 677 678 public void setBalloon(SWTBalloonWindow balloon) { 679 this.balloon = balloon; 680 } 681 682 public void run() { 683 display.syncExec(new Runnable () { 684 public void run() { 685 if (balloon != null && !balloon.getShell().isDisposed()) { 686 balloon.setVisible(false); 687 } 688 } 689 }); 690 } 691 } 692 693 } | Popular Tags |