package com.google.jstestdriver.idea.server.ui; import com.google.jstestdriver.idea.server.JstdBrowserInfo; import com.google.jstestdriver.idea.server.JstdServer; import com.google.jstestdriver.idea.server.JstdServerLifeCycleAdapter; import com.google.jstestdriver.idea.server.JstdServerSettings; import com.intellij.ide.BrowserUtil; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.ide.CopyPasteManager; import com.intellij.openapi.util.Ref; import com.intellij.ui.PopupHandler; import com.intellij.ui.SideBorder; import com.intellij.util.PlatformIcons; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.SwingHelper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; import java.awt.*; import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.Transferable; public class JstdServerStatusView { private final JEditorPane myInfoPane; private final JLabel myBrowsersLabel; private final JPanel myRoot; private final Disposable myDisposable; public JstdServerStatusView(@NotNull Disposable disposable) { myDisposable = disposable; myInfoPane = createInfoPane(); myBrowsersLabel = new JLabel(); JPanel panel = SwingHelper.newHorizontalPanel( Component.CENTER_ALIGNMENT, myInfoPane, Box.createHorizontalGlue(), myBrowsersLabel ); panel.setBorder(BorderFactory.createEmptyBorder(3, 7, 5, 12)); JPanel wrap = new JPanel(new BorderLayout(0, 0)); wrap.add(panel, BorderLayout.CENTER); wrap.setBorder(new SideBorder(UIUtil.getBorderColor(), SideBorder.BOTTOM)); myRoot = wrap; } @NotNull public JComponent getComponent() { return myRoot; } public void attachToServer(@NotNull final JstdServer server) { setInfoBodyHtml("Starting up..."); server.addLifeCycleListener(new JstdServerLifeCycleAdapter() { @Override public void onServerStarted() { JstdServerSettings settings = server.getSettings(); String url = "http://127.0.0.1:" + settings.getPort() + "/capture"; setInfoBodyHtml("To capture a browser open <a href='" + url + "'>" + url + "</a>"); updateCapturedBrowsersCount(server); } @Override public void onServerStopped() { setInfoBodyHtml("Not running"); updateCapturedBrowsersCount(server); } @Override public void onBrowserCaptured(@NotNull JstdBrowserInfo info) { updateCapturedBrowsersCount(server); } @Override public void onBrowserPanicked(@NotNull JstdBrowserInfo info) { updateCapturedBrowsersCount(server); } }, myDisposable); } private void updateCapturedBrowsersCount(@NotNull JstdServer server) { final int capturedBrowsers; if (server.isStopped()) { capturedBrowsers = 0; } else { capturedBrowsers = server.getCapturedBrowsers().size(); } myBrowsersLabel.setText("Captured browsers: " + capturedBrowsers); } private void setInfoBodyHtml(@NotNull String htmlBody) { String styleTag = UIUtil.getCssFontDeclaration(UIUtil.getLabelFont()); myInfoPane.setText("<html>" + styleTag + "<body>" + htmlBody + "</body></html>"); } @NotNull private static JEditorPane createInfoPane() { JEditorPane textPane = new JEditorPane(); textPane.setFont(UIUtil.getLabelFont()); textPane.setContentType(UIUtil.HTML_MIME); textPane.setEditable(false); textPane.setOpaque(false); textPane.setBackground(UIUtil.TRANSPARENT_COLOR); installLinkHandler(textPane); return textPane; } private static void installLinkHandler(@NotNull JEditorPane pane) { final Ref<String> urlRef = Ref.create(null); pane.addHyperlinkListener(new HyperlinkListener() { @Override public void hyperlinkUpdate(HyperlinkEvent e) { if (e.getEventType() == HyperlinkEvent.EventType.EXITED) { urlRef.set(null); } else if (e.getEventType() == HyperlinkEvent.EventType.ENTERED) { urlRef.set(e.getDescription()); } else if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { BrowserUtil.browse(e.getDescription()); } } }); final CopyLinkAction copyLinkAction = new CopyLinkAction(); final OpenLinkInBrowser openLinkInBrowserAction = new OpenLinkInBrowser(); final DefaultActionGroup group = new DefaultActionGroup(openLinkInBrowserAction, copyLinkAction); pane.addMouseListener(new PopupHandler() { public void invokePopup(Component comp, int x, int y) { String url = urlRef.get(); copyLinkAction.setUrl(url); openLinkInBrowserAction.setUrl(url); if (url != null) { ActionPopupMenu popupMenu = ActionManager.getInstance().createActionPopupMenu(ActionPlaces.UNKNOWN, group); popupMenu.getComponent().show(comp, x, y); } } }); } private static class OpenLinkInBrowser extends AnAction { private String myUrl; private OpenLinkInBrowser() { super("Open Link in Browser", null, PlatformIcons.WEB_ICON); } @Override public void update(AnActionEvent e) { e.getPresentation().setEnabledAndVisible(myUrl != null); } @Override public void actionPerformed(AnActionEvent e) { String url = myUrl; if (url != null) { BrowserUtil.browse(url); } } public void setUrl(@Nullable String url) { myUrl = url; } } private static class CopyLinkAction extends AnAction { private String myUrl; private CopyLinkAction() { super("Copy Link Address", null, PlatformIcons.COPY_ICON); } @Override public void update(AnActionEvent e) { e.getPresentation().setEnabledAndVisible(myUrl != null); } @Override public void actionPerformed(AnActionEvent e) { String url = myUrl; if (url != null) { Transferable content = new StringSelection(url); CopyPasteManager.getInstance().setContents(content); } } public void setUrl(@Nullable String url) { myUrl = url; } } }