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

com.intellij.ide.actions.AboutPopup Maven / Gradle / Ivy

Go to download

A packaging of the IntelliJ Community Edition platform-impl 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.actions;

import com.intellij.ide.BrowserUtil;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CustomShortcutSet;
import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.JBColor;
import com.intellij.ui.LicensingFacade;
import com.intellij.ui.UI;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.text.DateFormatUtil;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.StringSelection;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Properties;

/**
 * @author Konstantin Bulenkov
 */
public class AboutPopup {
  public void show(@Nullable Window window) {
    ApplicationInfoEx appInfo = (ApplicationInfoEx)ApplicationInfo.getInstance();

    final JPanel panel = new JPanel(new BorderLayout());
    Icon image = IconLoader.getIcon(appInfo.getAboutImageUrl());
    if (appInfo.showLicenseeInfo()) {
      final InfoSurface infoSurface = new InfoSurface(image);
      infoSurface.setPreferredSize(new Dimension(image.getIconWidth(), image.getIconHeight()));
      panel.add(infoSurface, BorderLayout.NORTH);

      new DumbAwareAction() {
        @Override
        public void actionPerformed(AnActionEvent e) {
          copyInfoToClipboard(infoSurface.getText());
        }
      }.registerCustomShortcutSet(CustomShortcutSet.fromString("meta C", "control C"), panel);
    }
    else {
      panel.add(new JLabel(image), BorderLayout.NORTH);
    }

    RelativePoint location;
    if (window != null) {
      Rectangle r = window.getBounds();
      location = new RelativePoint(window, new Point((r.width - image.getIconWidth()) / 2, (r.height - image.getIconHeight()) / 2));
    }
    else {
      Rectangle r = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().getBounds();
      location = new RelativePoint(new Point((r.width - image.getIconWidth()) / 2, (r.height - image.getIconHeight()) / 2));
    }

    JBPopupFactory.getInstance().createComponentPopupBuilder(panel, panel)
      .setRequestFocus(true)
      .setFocusable(true)
      .setResizable(false)
      .setMovable(false)
      .setModalContext(false)
      .setShowShadow(true)
      .setShowBorder(false)
      .setCancelKeyEnabled(true)
      .setCancelOnClickOutside(true)
      .setCancelOnOtherWindowOpen(true)
      .createPopup()
      .show(location);
  }

  private static void copyInfoToClipboard(String text) {
    try {
      CopyPasteManager.getInstance().setContents(new StringSelection(text));
    }
    catch (Exception ignore) { }
  }

  private static class InfoSurface extends JPanel {
    private final Color myColor;
    private final Color myLinkColor;
    private final Icon myImage;
    private Font myFont;
    private Font myBoldFont;
    private final List myLines = new ArrayList();
    private StringBuilder myInfo = new StringBuilder();
    private final List myLinks = new ArrayList();
    private Link myActiveLink;

    public InfoSurface(Icon image) {
      ApplicationInfoImpl appInfo = (ApplicationInfoImpl)ApplicationInfoEx.getInstanceEx();

      myImage = image;
      //noinspection UseJBColor
      myColor = Color.white;
      myLinkColor = appInfo.getAboutLinkColor() != null ? appInfo.getAboutLinkColor() : UI.getColor("link.foreground");

      setOpaque(false);
      setBackground(myColor);
      setFocusable(true);
      Calendar cal = appInfo.getBuildDate();
      myLines.add(new AboutBoxLine(appInfo.getFullApplicationName(), true, null));
      appendLast();

      String buildInfo = IdeBundle.message("about.box.build.number", appInfo.getBuild().asString());
      String buildDate = "";
      if (appInfo.getBuild().isSnapshot()) {
        buildDate = new SimpleDateFormat("HH:mm, ").format(cal.getTime());
      }
      buildDate += DateFormatUtil.formatAboutDialogDate(cal.getTime());
      buildInfo += IdeBundle.message("about.box.build.date", buildDate);
      myLines.add(new AboutBoxLine(buildInfo));
      appendLast();

      myLines.add(new AboutBoxLine(""));

      LicensingFacade provider = LicensingFacade.getInstance();
      if (provider != null) {
        myLines.add(new AboutBoxLine(provider.getLicensedToMessage(), true, null));
        for (String message : provider.getLicenseRestrictionsMessages()) {
          myLines.add(new AboutBoxLine(message));
        }
      }

      myLines.add(new AboutBoxLine(""));

      Properties properties = System.getProperties();
      String javaVersion = properties.getProperty("java.runtime.version", properties.getProperty("java.version", "unknown"));
      String arch = properties.getProperty("os.arch", "");
      myLines.add(new AboutBoxLine(IdeBundle.message("about.box.jre", javaVersion, arch)));
      appendLast();

      String vmVersion = properties.getProperty("java.vm.name", "unknown");
      String vmVendor = properties.getProperty("java.vendor", "unknown");
      myLines.add(new AboutBoxLine(IdeBundle.message("about.box.vm", vmVersion, vmVendor)));
      appendLast();

      String thirdParty = appInfo.getThirdPartySoftwareURL();
      if (thirdParty != null) {
        myLines.add(new AboutBoxLine(""));
        myLines.add(new AboutBoxLine(""));
        myLines.add(new AboutBoxLine("Powered by ").keepWithNext());
        myLines.add(new AboutBoxLine("open-source software", false, thirdParty).keepWithNext());
      }

      addMouseListener(new MouseAdapter() {
        @Override
        public void mousePressed(MouseEvent event) {
          if (myActiveLink != null) {
            event.consume();
            BrowserUtil.browse(myActiveLink.myUrl);
          }
        }
      });

      addMouseMotionListener(new MouseMotionAdapter() {
        @Override
        public void mouseMoved(MouseEvent event) {
          boolean hadLink = (myActiveLink != null);
          myActiveLink = null;
          for (Link link : myLinks) {
            if (link.myRectangle.contains(event.getPoint())) {
              myActiveLink = link;
              if (!hadLink) {
                setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
              }
              break;
            }
          }
          if (hadLink && myActiveLink == null) {
            setCursor(Cursor.getDefaultCursor());
          }
        }
      });
    }

    private void appendLast() {
      myInfo.append(myLines.get(myLines.size() - 1).getText()).append("\n");
    }

    @Override
    protected void paintChildren(Graphics g) {
      super.paintChildren(g);

      Graphics2D g2 = (Graphics2D)g;
      UISettings.setupAntialiasing(g);

      Font labelFont = JBUI.Fonts.label();
      if (SystemInfo.isWindows) {
        labelFont = JBUI.Fonts.create("Tahoma", 12);
      }

      for (int labelSize = JBUI.scale(10); labelSize != JBUI.scale(6); labelSize -= 1) {
        myLinks.clear();
        g2.setPaint(myColor);
        myImage.paintIcon(this, g2, 0, 0);

        g2.setColor(myColor);
        TextRenderer renderer = new TextRenderer(0, 165, 398, 120, g2);
        UIUtil.setupComposite(g2);
        myFont = labelFont.deriveFont(Font.PLAIN, labelSize);
        myBoldFont = labelFont.deriveFont(Font.BOLD, labelSize + 1);
        try {
          renderer.render(30, 0, myLines);
          break;
        }
        catch (TextRenderer.OverflowException ignore) { }
      }

      ApplicationInfo appInfo = ApplicationInfo.getInstance();
      Rectangle aboutLogoRect = appInfo.getAboutLogoRect();
      if (aboutLogoRect != null) {
        myLinks.add(new Link(aboutLogoRect, appInfo.getCompanyURL()));
      }

      if (appInfo instanceof ApplicationInfoImpl) {
        g2.setColor(((ApplicationInfoImpl)appInfo).getCopyrightForeground());
        if (SystemInfo.isMac) {
          g2.setFont(JBUI.Fonts.miniFont());
        }
        else {
          g2.setFont(JBUI.Fonts.create("Tahoma", 10));
        }
      } else {
        g2.setColor(JBColor.BLACK);
      }
      g2.drawString("\u00A9 2000\u2013" + Calendar.getInstance().get(Calendar.YEAR) + " JetBrains s.r.o. All rights reserved.", JBUI.scale(30), JBUI.scale(284));
    }

    public String getText() {
      return myInfo.toString();
    }

    private class TextRenderer {
      private final int xBase;
      private final int yBase;
      private final int w;
      private final int h;
      private final Graphics2D g2;

      private int x = 0;
      private int y = 0;
      private FontMetrics fontmetrics;
      private int fontAscent;
      private int fontHeight;
      private Font font;

      public class OverflowException extends Exception { }

      public TextRenderer(final int xBase, final int yBase, final int w, final int h, final Graphics2D g2) {
        this.xBase = JBUI.scale(xBase);
        this.yBase = JBUI.scale(yBase);
        this.w = JBUI.scale(w);
        this.h = JBUI.scale(h);
        this.g2 = g2;

        if (SystemInfo.isWindows) {
          g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
        }
      }

      public void render(int indentX, int indentY, List lines) throws OverflowException {
        x = indentX;
        y = indentY;
        ApplicationInfoEx appInfo = (ApplicationInfoEx)ApplicationInfo.getInstance();
        for (AboutBoxLine line : lines) {
          final String s = line.getText();
          setFont(line.isBold() ? myBoldFont : myFont);
          if (line.getUrl() != null) {
            g2.setColor(myLinkColor);
            FontMetrics metrics = g2.getFontMetrics(font);
            myLinks.add(new Link(new Rectangle(x, yBase + y - fontAscent, metrics.stringWidth(s), fontHeight), line.getUrl()));
          }
          else {
            g2.setColor(appInfo.getAboutForeground());
          }
          renderString(s, indentX);
          if (!line.isKeepWithNext() && !line.equals(lines.get(lines.size()-1))) {
            lineFeed(indentX, s);
          }
        }
      }

      private void renderString(final String s, final int indentX) throws OverflowException {
        final List words = StringUtil.split(s, " ");
        for (String word : words) {
          int wordWidth = fontmetrics.stringWidth(word);
          if (x + wordWidth >= w) {
            lineFeed(indentX, word);
          }
          else {
            char c = ' ';
            final int cW = fontmetrics.charWidth(c);
            if (x + cW < w) {
              g2.drawChars(new char[]{c}, 0, 1, xBase + x, yBase + y);
              x += cW;
            }
          }
          renderWord(word, indentX);
        }
      }

      private void renderWord(final String s, final int indentX) throws OverflowException {
        for (int j = 0; j != s.length(); ++j) {
          final char c = s.charAt(j);
          final int cW = fontmetrics.charWidth(c);
          if (x + cW >= w) {
            lineFeed(indentX, s);
          }
          g2.drawChars(new char[]{c}, 0, 1, xBase + x, yBase + y);
          x += cW;
        }
      }

      private void lineFeed(int indent, final String s) throws OverflowException {
        x = indent;
        if (s.length() == 0) {
          y += fontHeight / 3;
        }
        else {
          y += fontHeight;
        }
        if (y >= h) {
          throw new OverflowException();
        }
      }

      private void setFont(Font font) {
        this.font = font;
        fontmetrics = g2.getFontMetrics(font);
        g2.setFont(font);
        fontAscent = fontmetrics.getAscent();
        fontHeight = fontmetrics.getHeight();
      }
    }

    private static class AboutBoxLine {
      private final String myText;
      private final boolean myBold;
      private final String myUrl;
      private boolean myKeepWithNext;

      public AboutBoxLine(final String text, final boolean bold, final String url) {
        myText = text;
        myBold = bold;
        myUrl = url;
      }

      public AboutBoxLine(final String text) {
        myText = text;
        myBold = false;
        myUrl = null;
      }

      public String getText() {
        return myText;
      }

      public boolean isBold() {
        return myBold;
      }

      public String getUrl() {
        return myUrl;
      }

      public boolean isKeepWithNext() {
        return myKeepWithNext;
      }

      public AboutBoxLine keepWithNext() {
        myKeepWithNext = true;
        return this;
      }
    }

    private static class Link {
      private final Rectangle myRectangle;
      private final String myUrl;

      private Link(Rectangle rectangle, String url) {
        myRectangle = rectangle;
        myUrl = url;
      }
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy