All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.intellij.ide.browsers.actions.BaseOpenInBrowserAction Maven / Gradle / Ivy

Go to download

A packaging of the IntelliJ Community Edition xml library. This is release number 1 of trunk branch 142.

The newest version!
/*
 * Copyright 2000-2015 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.intellij.ide.browsers.actions;

import com.intellij.icons.AllIcons;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.browsers.*;
import com.intellij.ide.browsers.impl.WebBrowserServiceImpl;
import com.intellij.internal.statistic.UsageTrigger;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.ui.ColoredListCellRenderer;
import com.intellij.ui.components.JBList;
import com.intellij.util.Consumer;
import com.intellij.util.ObjectUtils;
import com.intellij.util.Url;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.xml.util.HtmlUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.concurrency.AsyncPromise;
import org.jetbrains.concurrency.Promise;

import javax.swing.*;
import java.awt.event.InputEvent;
import java.util.Collection;

public abstract class BaseOpenInBrowserAction extends DumbAwareAction {
  private static final Logger LOG = Logger.getInstance(BaseOpenInBrowserAction.class);

  protected BaseOpenInBrowserAction(@NotNull WebBrowser browser) {
    super(browser.getName(), null, browser.getIcon());
  }

  @SuppressWarnings("UnusedDeclaration")
  protected BaseOpenInBrowserAction(@Nullable String text, @Nullable String description, @Nullable Icon icon) {
    super(text, description, icon);
  }

  @Nullable
  protected abstract WebBrowser getBrowser(@NotNull AnActionEvent event);

  @Override
  public final void update(AnActionEvent e) {
    WebBrowser browser = getBrowser(e);
    if (browser == null) {
      e.getPresentation().setEnabledAndVisible(false);
      return;
    }

    OpenInBrowserRequest result = doUpdate(e);
    if (result == null) {
      return;
    }

    String description = getTemplatePresentation().getText();
    if (ActionPlaces.CONTEXT_TOOLBAR.equals(e.getPlace())) {
      StringBuilder builder = new StringBuilder(description);
      builder.append(" (");
      Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts("WebOpenInAction");
      boolean exists = shortcuts.length > 0;
      if (exists) {
        builder.append(KeymapUtil.getShortcutText(shortcuts[0]));
      }

      if (HtmlUtil.isHtmlFile(result.getFile())) {
        builder.append(exists ? ", " : "").append("hold Shift to open URL of local file");
      }
      builder.append(')');
      description = builder.toString();
    }
    e.getPresentation().setText(description);
  }

  @Override
  public final void actionPerformed(AnActionEvent e) {
    WebBrowser browser = getBrowser(e);
    if (browser != null) {
      UsageTrigger.trigger("OpenInBrowser." + browser.getName());
      open(e, browser);
    }
  }

  @Nullable
  public static OpenInBrowserRequest createRequest(@NotNull DataContext context) {
    final Editor editor = CommonDataKeys.EDITOR.getData(context);
    if (editor != null) {
      Project project = editor.getProject();
      if (project != null && project.isInitialized()) {
        PsiFile psiFile = CommonDataKeys.PSI_FILE.getData(context);
        if (psiFile == null) {
          psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
        }
        if (psiFile != null) {
          return new OpenInBrowserRequest(psiFile) {
            private PsiElement element;

            @NotNull
            @Override
            public PsiElement getElement() {
              if (element == null) {
                element = getFile().findElementAt(editor.getCaretModel().getOffset());
              }
              return ObjectUtils.chooseNotNull(element, getFile());
            }
          };
        }
      }
    }
    else {
      PsiFile psiFile = CommonDataKeys.PSI_FILE.getData(context);
      VirtualFile virtualFile = CommonDataKeys.VIRTUAL_FILE.getData(context);
      Project project = CommonDataKeys.PROJECT.getData(context);
      if (virtualFile != null && !virtualFile.isDirectory() && virtualFile.isValid() && project != null && project.isInitialized()) {
        psiFile = PsiManager.getInstance(project).findFile(virtualFile);
      }

      if (psiFile != null) {
        return OpenInBrowserRequest.create(psiFile);
      }
    }
    return null;
  }

  @Nullable
  public static OpenInBrowserRequest doUpdate(@NotNull AnActionEvent event) {
    OpenInBrowserRequest request = createRequest(event.getDataContext());
    boolean applicable = request != null && WebBrowserServiceImpl.getProvider(request) != null;
    event.getPresentation().setEnabledAndVisible(applicable);
    return applicable ? request : null;
  }

  public static void open(@NotNull AnActionEvent event, @Nullable WebBrowser browser) {
    open(createRequest(event.getDataContext()), (event.getModifiers() & InputEvent.SHIFT_MASK) != 0, browser);
  }

  public static void open(@Nullable final OpenInBrowserRequest request, boolean preferLocalUrl, @Nullable final WebBrowser browser) {
    if (request == null) {
      return;
    }

    try {
      Collection urls = WebBrowserService.getInstance().getUrlsToOpen(request, preferLocalUrl);
      if (!urls.isEmpty()) {
        chooseUrl(urls)
          .done(new Consumer() {
            @Override
            public void consume(Url url) {
              ApplicationManager.getApplication().saveAll();
              BrowserLauncher.getInstance().browse(url.toExternalForm(), browser, request.getProject());
            }
          });
      }
    }
    catch (WebBrowserUrlProvider.BrowserException e1) {
      Messages.showErrorDialog(e1.getMessage(), IdeBundle.message("browser.error"));
    }
    catch (Exception e1) {
      LOG.error(e1);
    }
  }

  @NotNull
  private static Promise chooseUrl(@NotNull Collection urls) {
    if (urls.size() == 1) {
      return Promise.resolve(ContainerUtil.getFirstItem(urls));
    }

    final JBList list = new JBList(urls);
    list.setCellRenderer(new ColoredListCellRenderer() {
      @Override
      protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {
        // todo icons looks good, but is it really suitable for all URLs providers?
        setIcon(AllIcons.Nodes.Servlet);
        append(((Url)value).toDecodedForm());
      }
    });

    final AsyncPromise result = new AsyncPromise();
    JBPopupFactory.getInstance()
      .createListPopupBuilder(list)
      .setTitle("Choose Url")
      .setItemChoosenCallback(new Runnable() {
        @Override
        public void run() {
          Url value = (Url)list.getSelectedValue();
          if (value == null) {
            result.setError(Promise.createError("selected value is null"));
          }
          else {
            result.setResult(value);
          }
        }
      })
      .createPopup()
      .showInFocusCenter();
    return result;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy