sticky documentation popup [take 1]
[fedora-idea.git] / platform / platform-impl / src / com / intellij / openapi / wm / impl / IdeFrameImpl.java
blob437798bfb9127b1bc1127693d182ca04bca30b5c
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.openapi.wm.impl;
18 import com.intellij.ide.AppLifecycleListener;
19 import com.intellij.ide.DataManager;
20 import com.intellij.ide.impl.ProjectUtil;
21 import com.intellij.ide.ui.UISettings;
22 import com.intellij.openapi.MnemonicHelper;
23 import com.intellij.openapi.actionSystem.ActionManager;
24 import com.intellij.openapi.actionSystem.DataProvider;
25 import com.intellij.openapi.actionSystem.PlatformDataKeys;
26 import com.intellij.openapi.application.Application;
27 import com.intellij.openapi.application.ApplicationInfo;
28 import com.intellij.openapi.application.ApplicationManager;
29 import com.intellij.openapi.application.ModalityState;
30 import com.intellij.openapi.application.ex.ApplicationInfoEx;
31 import com.intellij.openapi.application.ex.ApplicationManagerEx;
32 import com.intellij.openapi.keymap.KeymapManager;
33 import com.intellij.openapi.project.DumbAwareRunnable;
34 import com.intellij.openapi.project.Project;
35 import com.intellij.openapi.project.ProjectManager;
36 import com.intellij.openapi.wm.IdeFrame;
37 import com.intellij.openapi.wm.ex.LayoutFocusTraversalPolicyExt;
38 import com.intellij.openapi.wm.ex.StatusBarEx;
39 import com.intellij.ui.AppUIUtil;
40 import com.intellij.ui.BalloonLayout;
41 import com.intellij.ui.FocusTrackback;
42 import com.intellij.util.ui.UIUtil;
43 import org.jetbrains.annotations.NotNull;
44 import org.jetbrains.annotations.Nullable;
46 import javax.swing.*;
47 import java.awt.*;
48 import java.awt.event.WindowAdapter;
49 import java.awt.event.WindowEvent;
50 import java.io.File;
52 /**
53 * @author Anton Katilin
54 * @author Vladimir Kondratyev
57 // Made non-final for Fabrique
58 public class IdeFrameImpl extends JFrame implements IdeFrame, DataProvider {
59 private String myTitle;
61 private String myFileTitle;
62 private File myCurrentFile;
64 private Project myProject;
65 private final LayoutFocusTraversalPolicyExt myLayoutFocusTraversalPolicy;
67 private IdeRootPane myRootPane;
68 private BalloonLayout myBalloonLayout;
70 public IdeFrameImpl(ApplicationInfoEx applicationInfoEx, ActionManager actionManager, UISettings uiSettings, DataManager dataManager,
71 KeymapManager keymapManager, final Application application, final String[] commandLineArgs) {
72 super(applicationInfoEx.getFullApplicationName());
73 myRootPane = new IdeRootPane(actionManager, uiSettings, dataManager, keymapManager, application, commandLineArgs);
74 setRootPane(myRootPane);
76 AppUIUtil.updateFrameIcon(this);
77 final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
78 setBounds(10, 10, screenSize.width - 20, screenSize.height - 40);
80 myLayoutFocusTraversalPolicy = new LayoutFocusTraversalPolicyExt();
81 setFocusTraversalPolicy(myLayoutFocusTraversalPolicy);
83 setupCloseAction();
84 new MnemonicHelper().register(this);
86 myBalloonLayout = new BalloonLayout(myRootPane.getLayeredPane(), new Insets(8, 8, 8, 8));
89 /**
90 * !!!!! CAUTION !!!!!
91 * !!!!! CAUTION !!!!!
92 * !!!!! CAUTION !!!!!
94 * THIS IS AN "ABSOLUTELY-GURU METHOD".
95 * NOBODY SHOULD ADD OTHER USAGES OF IT :)
96 * ONLY ANTON AND VOVA ARE PERMITTED TO USE THIS METHOD!!!
98 * !!!!! CAUTION !!!!!
99 * !!!!! CAUTION !!!!!
100 * !!!!! CAUTION !!!!!
102 public final void setDefaultFocusableComponent(final JComponent component) {
103 myLayoutFocusTraversalPolicy.setOverridenDefaultComponent(component);
107 * This is overriden to get rid of strange Alloy LaF customization of frames. For unknown reason it sets the maxBounds rectangle
108 * and it does it plain wrong. Setting bounds to <code>null</code> means default value should be taken from the underlying OS.
110 public synchronized void setMaximizedBounds(Rectangle bounds) {
111 super.setMaximizedBounds(null);
114 private void setupCloseAction() {
115 setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
116 addWindowListener(
117 new WindowAdapter() {
118 public void windowClosing(final WindowEvent e) {
119 final Application app = ApplicationManager.getApplication();
120 app.invokeLater(new DumbAwareRunnable() {
121 public void run() {
122 if (app.isDisposed()) {
123 ApplicationManagerEx.getApplicationEx().exit();
124 return;
127 final Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
128 if (openProjects.length > 1) {
129 if (myProject != null && myProject.isOpen()) {
130 ProjectUtil.closeProject(myProject);
132 app.getMessageBus().syncPublisher(AppLifecycleListener.TOPIC).projectFrameClosed();
134 else {
135 ApplicationManagerEx.getApplicationEx().exit();
138 }, ModalityState.NON_MODAL);
144 public StatusBarEx getStatusBar() {
145 return ((IdeRootPane)getRootPane()).getStatusBar();
148 public void updateToolbar() {
149 ((IdeRootPane)getRootPane()).updateToolbar();
152 public void updateMenuBar(){
153 ((IdeRootPane)getRootPane()).updateMainMenuActions();
156 public void setTitle(final String title) {
157 myTitle = title;
158 updateTitle();
161 private void setFrameTitle(final String text) {
162 super.setTitle(text);
165 public void setFileTitle(final String fileTitle) {
166 setFileTitle(fileTitle, null);
169 public void setFileTitle(@Nullable final String fileTitle, @Nullable File file) {
170 myFileTitle = fileTitle;
171 myCurrentFile = file;
172 updateTitle();
175 private void updateTitle() {
176 final StringBuilder sb = new StringBuilder();
177 if (myTitle != null && myTitle.length() > 0) {
178 sb.append(myTitle);
179 sb.append(" - ");
181 if (myFileTitle != null && myFileTitle.length() > 0) {
182 sb.append(myFileTitle);
183 sb.append(" - ");
186 getRootPane().putClientProperty("Window.documentFile", myCurrentFile);
188 sb.append(((ApplicationInfoEx)ApplicationInfo.getInstance()).getFullApplicationName());
189 setFrameTitle(sb.toString());
192 public Object getData(final String dataId) {
193 if (PlatformDataKeys.PROJECT.is(dataId)) {
194 if (myProject != null) {
195 return myProject.isInitialized() ? myProject : null;
198 return null;
201 public void setProject(final Project project) {
202 getStatusBar().cleanupCustomComponents();
203 myProject = project;
204 if (project != null) {
205 if (myRootPane != null) {
206 myRootPane.installNorthComponents(project);
209 else {
210 if (myRootPane != null) { //already disposed
211 myRootPane.deinstallNorthComponents();
215 if (project == null) {
216 FocusTrackback.release(this);
220 public Project getProject() {
221 return myProject;
224 public void dispose() {
225 if (myRootPane != null) {
226 myRootPane = null;
228 super.dispose();
231 @Override
232 public void paint(Graphics g) {
233 UIUtil.applyRenderingHints(g);
234 super.paint(g);
237 public Rectangle suggestChildFrameBounds() {
238 //todo [kirillk] a dummy implementation
239 final Rectangle b = getBounds();
240 b.x += 100;
241 b.width -= 200;
242 b.y += 100;
243 b.height -= 200;
244 return b;
247 @Nullable
248 public static Component findNearestModalComponent(@NotNull Component c) {
249 Component eachParent = c;
250 while (eachParent != null) {
251 if (eachParent instanceof IdeFrameImpl) return eachParent;
252 if (eachParent instanceof JDialog) {
253 if (((JDialog)eachParent).isModal()) return eachParent;
255 eachParent = eachParent.getParent();
258 return null;
261 public final BalloonLayout getBalloonLayout() {
262 return myBalloonLayout;