toolwindow resize for docked windows
[fedora-idea.git] / platform / platform-impl / src / com / intellij / ide / actions / AboutAction.java
blob74e5034d90db2b132856ddf81db3194b231ea771
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.ide.actions;
18 import com.intellij.Patches;
19 import com.intellij.ide.BrowserUtil;
20 import com.intellij.ide.DataManager;
21 import com.intellij.ide.IdeBundle;
22 import com.intellij.openapi.actionSystem.AnAction;
23 import com.intellij.openapi.actionSystem.AnActionEvent;
24 import com.intellij.openapi.actionSystem.PlatformDataKeys;
25 import com.intellij.openapi.application.ApplicationInfo;
26 import com.intellij.openapi.application.ApplicationNamesInfo;
27 import com.intellij.openapi.application.ex.ApplicationInfoEx;
28 import com.intellij.openapi.project.DumbAware;
29 import com.intellij.openapi.util.IconLoader;
30 import com.intellij.openapi.util.SystemInfo;
31 import com.intellij.openapi.util.text.StringUtil;
32 import com.intellij.openapi.wm.WindowManager;
33 import com.intellij.ui.LicenseeInfoProvider;
34 import com.intellij.util.ImageLoader;
35 import com.intellij.util.ui.UIUtil;
36 import org.jetbrains.annotations.NonNls;
38 import javax.swing.*;
39 import java.awt.*;
40 import java.awt.event.*;
41 import java.text.DateFormat;
42 import java.util.ArrayList;
43 import java.util.Calendar;
44 import java.util.List;
45 import java.util.Properties;
47 public class AboutAction extends AnAction implements DumbAware {
48 @NonNls private static final String COMPANY_URL = "http://www.jetbrains.com/"; // TODO move to ApplicationInfo.xml
50 public void update(AnActionEvent e) {
51 e.getPresentation().setVisible(!SystemInfo.isMacSystemMenu);
52 e.getPresentation().setDescription("Show information about " + ApplicationNamesInfo.getInstance().getFullProductName());
55 public void actionPerformed(AnActionEvent e) {
56 Window window = WindowManager.getInstance().suggestParentWindow(e.getData(PlatformDataKeys.PROJECT));
58 showAboutDialog(window);
61 public static void showAbout() {
62 Window window = WindowManager.getInstance().suggestParentWindow(
63 PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext()));
65 showAboutDialog(window);
68 private static void showAboutDialog(Window window) {
69 ApplicationInfoEx appInfo = (ApplicationInfoEx)ApplicationInfo.getInstance();
70 JPanel mainPanel = new JPanel(new BorderLayout());
71 final JComponent closeListenerOwner;
72 if (appInfo.showLicenseeInfo()) {
73 final Image image = ImageLoader.loadFromResource(appInfo.getAboutLogoUrl());
74 final InfoSurface infoSurface = new InfoSurface(image);
75 infoSurface.setPreferredSize(new Dimension(image.getWidth(null), image.getHeight(null)));
76 mainPanel.add(infoSurface, BorderLayout.NORTH);
78 closeListenerOwner = infoSurface;
80 else {
81 mainPanel.add(new JLabel(IconLoader.getIcon(appInfo.getAboutLogoUrl())), BorderLayout.NORTH);
82 closeListenerOwner = mainPanel;
85 final JDialog dialog;
86 if (window instanceof Dialog) {
87 dialog = new JDialog((Dialog)window);
89 else {
90 dialog = new JDialog((Frame)window);
92 dialog.setUndecorated(true);
93 dialog.setContentPane(mainPanel);
94 dialog.addKeyListener(new KeyAdapter() {
95 public void keyPressed(KeyEvent e) {
96 if (e.getKeyCode() == KeyEvent.VK_ESCAPE && e.getModifiers() == 0) {
97 dialog.dispose();
102 final long showTime = System.currentTimeMillis();
103 final long delta = Patches.APPLE_BUG_ID_3716865 ? 100 : 0;
105 dialog.addWindowFocusListener(new WindowFocusListener() {
106 public void windowGainedFocus(WindowEvent e) {}
108 public void windowLostFocus(WindowEvent e) {
109 long eventTime = System.currentTimeMillis();
110 if (eventTime - showTime > delta && e.getOppositeWindow() != e.getWindow()) {
111 dialog.dispose();
116 closeListenerOwner.addMouseListener(new MouseAdapter() {
117 public void mouseClicked(MouseEvent e) {
118 if (!e.isConsumed()) {
119 dialog.dispose();
120 e.consume();
125 dialog.pack();
127 dialog.setLocationRelativeTo(window);
128 dialog.setVisible(true);
131 private static class AboutBoxLine {
132 private final String myText;
133 private final boolean myBold;
134 private final boolean myLink;
136 public AboutBoxLine(final String text, final boolean bold, final boolean link) {
137 myLink = link;
138 myText = text;
139 myBold = bold;
142 public AboutBoxLine(final String text) {
143 myText = text;
144 myBold = false;
145 myLink = false;
149 public String getText() {
150 return myText;
153 public boolean isBold() {
154 return myBold;
157 public boolean isLink() {
158 return myLink;
162 private static class InfoSurface extends JPanel {
163 final Color col;
164 final Color linkCol;
165 private final Image myImage;
166 private Font myFont;
167 private Font myBoldFont;
168 private final List<AboutBoxLine> myLines = new ArrayList<AboutBoxLine>();
169 private int linkX;
170 private int linkY;
171 private int linkWidth;
172 private boolean inLink = false;
174 public InfoSurface(Image image) {
175 myImage = image;
178 setOpaque(false);
179 //col = new Color(0xfa, 0xfa, 0xfa, 200);
180 col = Color.white;
181 linkCol = Color.blue;
182 setBackground(col);
183 ApplicationInfoEx ideInfo = (ApplicationInfoEx)ApplicationInfo.getInstance();
184 Calendar cal = ideInfo.getBuildDate();
185 myLines.add(new AboutBoxLine(ideInfo.getFullApplicationName(), true, false));
186 myLines.add(new AboutBoxLine(IdeBundle.message("aboutbox.build.number", ideInfo.getBuild().asString())));
187 myLines.add(new AboutBoxLine(IdeBundle.message("aboutbox.build.date", DateFormat.getDateInstance(DateFormat.LONG).format(cal.getTime()))));
188 myLines.add(new AboutBoxLine(""));
189 LicenseeInfoProvider provider = LicenseeInfoProvider.getInstance();
190 if (provider != null) {
191 myLines.add(new AboutBoxLine(provider.getLicensedToMessage(), true, false));
192 myLines.add(new AboutBoxLine(provider.getLicenseRestrictionsMessage()));
194 myLines.add(new AboutBoxLine(""));
197 final Properties properties = System.getProperties();
198 myLines.add(new AboutBoxLine(IdeBundle.message("aboutbox.jdk", properties.getProperty("java.version", "unknown")), true, false));
199 myLines.add(new AboutBoxLine(IdeBundle.message("aboutbox.vm", properties.getProperty("java.vm.name", "unknown"))));
200 myLines.add(new AboutBoxLine(IdeBundle.message("aboutbox.vendor", properties.getProperty("java.vendor", "unknown"))));
202 myLines.add(new AboutBoxLine(""));
203 myLines.add(new AboutBoxLine("JetBrains s.r.o.", true, false));
204 myLines.add(new AboutBoxLine(COMPANY_URL, true, true));
205 addMouseListener(new MouseAdapter() {
206 public void mousePressed(MouseEvent event) {
207 if (inLink) {
208 event.consume();
209 BrowserUtil.launchBrowser(COMPANY_URL);
213 addMouseMotionListener(new MouseMotionAdapter() {
214 public void mouseMoved(MouseEvent event) {
215 if (
216 event.getPoint().x > linkX && event.getPoint().y >= linkY &&
217 event.getPoint().x < linkX + linkWidth && event.getPoint().y < linkY + 10
219 if (!inLink) {
220 setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
221 inLink = true;
224 else {
225 if (inLink) {
226 setCursor(Cursor.getDefaultCursor());
227 inLink = false;
234 @Override
235 protected void paintChildren(Graphics g) {
236 super.paintChildren(g);
237 Graphics2D g2 = (Graphics2D)g;
239 Font labelFont = UIUtil.getLabelFont();
240 for (int labelSize = 10; labelSize != 6; labelSize -= 1) {
241 g2.setPaint(col);
242 g2.drawImage(myImage, 0, 0, this);
244 g2.setColor(col);
245 TextRenderer renderer = new TextRenderer(0, 145, 398, 120, g2);
246 g2.setComposite(AlphaComposite.Src);
247 myFont = labelFont.deriveFont(Font.PLAIN, labelSize);
248 myBoldFont = labelFont.deriveFont(Font.BOLD, labelSize+1);
249 try {
250 renderer.render (75, 0, myLines);
251 break;
253 catch (TextRenderer.OverflowException _) {
254 // ignore
259 public class TextRenderer {
260 private final int xBase;
261 private final int yBase;
262 private final int w;
263 private final int h;
264 private final Graphics2D g2;
266 private int x = 0;
267 private int y = 0;
268 private FontMetrics fontmetrics;
269 private int fontAscent;
270 private int fontHeight;
271 private Font font;
273 public class OverflowException extends Exception { }
275 public TextRenderer(final int xBase, final int yBase, final int w, final int h, final Graphics2D g2) {
276 this.xBase = xBase;
277 this.yBase = yBase;
278 this.w = w;
279 this.h = h;
280 this.g2 = g2;
282 if (SystemInfo.isWindows) {
283 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
289 public void render(int indentX, int indentY, List<AboutBoxLine> lines) throws OverflowException {
290 x = indentX;
291 y = indentY;
292 g2.setColor(Color.black);
293 for (int i = 0; i < lines.size(); i++) {
294 AboutBoxLine line = lines.get(i);
295 final String s = line.getText();
296 setFont (line.isBold() ? myBoldFont : myFont);
297 if (line.isLink()) {
298 g2.setColor(linkCol);
299 linkX = x;
300 linkY = yBase + y - fontAscent;
301 FontMetrics metrics = g2.getFontMetrics(font);
302 linkWidth = metrics.stringWidth (s);
304 renderString(s, indentX);
305 if (i == lines.size()-2) {
306 x += 50;
308 else if (i < lines.size()-1) {
309 lineFeed (indentX, s);
314 private void renderString(final String s, final int indentX) throws OverflowException {
315 final List<String> words = StringUtil.split(s, " ");
316 for (String word : words) {
317 int wordWidth = fontmetrics.stringWidth(word);
318 if (x + wordWidth >= w) {
319 lineFeed(indentX, word);
321 else {
322 char c = ' ';
323 final int cW = fontmetrics.charWidth(c);
324 if (x + cW < w) {
325 g2.drawChars(new char[]{c}, 0, 1, xBase + x, yBase + y);
326 x += cW;
329 renderWord(word, indentX);
333 private void renderWord(final String s, final int indentX) throws OverflowException {
334 for (int j = 0; j != s.length(); ++ j) {
335 final char c = s.charAt(j);
336 final int cW = fontmetrics.charWidth(c);
337 if (x + cW >= w) {
338 lineFeed(indentX, s);
340 g2.drawChars(new char[]{c}, 0, 1, xBase + x, yBase + y);
341 x += cW;
345 private void lineFeed(int indent, final String s) throws OverflowException {
346 x = indent;
347 if (s.length() == 0) {
348 y += fontHeight/3;
350 else {
351 y += fontHeight;
353 if (y >= h)
354 throw new OverflowException();
357 private void setFont(Font font) {
358 this.font = font;
359 fontmetrics = g2.getFontMetrics(font);
360 g2.setFont (font);
361 fontAscent = fontmetrics.getAscent();
362 fontHeight = fontmetrics.getHeight();