blob: b32729dd7328646adfcbbbba936467f0f6424946 [file] [log] [blame]
/*
* Copyright 2000-2014 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.idea;
import com.intellij.ExtensionPoints;
import com.intellij.Patches;
import com.intellij.ide.AppLifecycleListener;
import com.intellij.ide.CommandLineProcessor;
import com.intellij.ide.IdeEventQueue;
import com.intellij.ide.IdeRepaintManager;
import com.intellij.ide.plugins.PluginManager;
import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.internal.statistic.UsageTrigger;
import com.intellij.openapi.application.*;
import com.intellij.openapi.application.ex.ApplicationEx;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.ExtensionPoint;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.openapi.wm.impl.SystemDock;
import com.intellij.openapi.wm.impl.WindowManagerImpl;
import com.intellij.openapi.wm.impl.X11UiUtil;
import com.intellij.openapi.wm.impl.welcomeScreen.WelcomeFrame;
import com.intellij.ui.Splash;
import com.intellij.util.messages.MessageBus;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.Arrays;
public class IdeaApplication {
@NonNls public static final String IDEA_IS_INTERNAL_PROPERTY = "idea.is.internal";
@NonNls public static final String IDEA_IS_UNIT_TEST = "idea.is.unit.test";
private static final Logger LOG = Logger.getInstance("#com.intellij.idea.IdeaApplication");
private static IdeaApplication ourInstance;
public static IdeaApplication getInstance() {
return ourInstance;
}
public static boolean isLoaded() {
return ourInstance != null && ourInstance.myLoaded;
}
private final String[] myArgs;
private boolean myPerformProjectLoad = true;
private ApplicationStarter myStarter;
private volatile boolean myLoaded = false;
public IdeaApplication(String[] args) {
LOG.assertTrue(ourInstance == null);
//noinspection AssignmentToStaticFieldFromInstanceMethod
ourInstance = this;
myArgs = args;
boolean isInternal = Boolean.getBoolean(IDEA_IS_INTERNAL_PROPERTY);
boolean isUnitTest = Boolean.getBoolean(IDEA_IS_UNIT_TEST);
boolean headless = Main.isHeadless();
if (!headless) {
patchSystem();
}
if (Main.isCommandLine()) {
new CommandLineApplication(isInternal, isUnitTest, headless);
}
else {
Splash splash = null;
if (myArgs.length == 0) {
myStarter = getStarter();
if (myStarter instanceof IdeStarter) {
splash = ((IdeStarter)myStarter).showSplash(myArgs);
}
}
ApplicationManagerEx.createApplication(isInternal, isUnitTest, false, false, ApplicationManagerEx.IDEA_APPLICATION, splash);
}
if (myStarter == null) {
myStarter = getStarter();
}
if (headless && myStarter instanceof ApplicationStarterEx && !((ApplicationStarterEx)myStarter).isHeadless()) {
Main.showMessage("Startup Error", "Application cannot start in headless mode", true);
System.exit(Main.STARTUP_IMPOSSIBLE);
}
myStarter.premain(args);
}
private static void patchSystem() {
System.setProperty("sun.awt.noerasebackground", "true");
Toolkit.getDefaultToolkit().getSystemEventQueue().push(IdeEventQueue.getInstance());
if (Patches.SUN_BUG_ID_6209673) {
RepaintManager.setCurrentManager(new IdeRepaintManager());
}
if (SystemInfo.isXWindow) {
String wmName = X11UiUtil.getWmName();
LOG.info("WM detected: " + wmName);
if (wmName != null) {
X11UiUtil.patchDetectedWm(wmName);
}
}
IconLoader.activate();
new JFrame().pack(); // this peer will prevent shutting down our application
}
protected ApplicationStarter getStarter() {
if (myArgs.length > 0) {
PluginManagerCore.getPlugins();
ExtensionPoint<ApplicationStarter> point = Extensions.getRootArea().getExtensionPoint(ExtensionPoints.APPLICATION_STARTER);
ApplicationStarter[] starters = point.getExtensions();
String key = myArgs[0];
for (ApplicationStarter o : starters) {
if (Comparing.equal(o.getCommandName(), key)) return o;
}
}
return new IdeStarter();
}
public void run() {
try {
ApplicationEx app = ApplicationManagerEx.getApplicationEx();
app.load(PathManager.getOptionsPath());
myStarter.main(myArgs);
myStarter = null; //GC it
myLoaded = true;
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings({"HardCodedStringLiteral"})
private static void initLAF() {
try {
Class.forName("com.jgoodies.looks.plastic.PlasticLookAndFeel");
if (SystemInfo.isWindows) {
UIManager.installLookAndFeel("JGoodies Windows L&F", "com.jgoodies.looks.windows.WindowsLookAndFeel");
}
UIManager.installLookAndFeel("JGoodies Plastic", "com.jgoodies.looks.plastic.PlasticLookAndFeel");
UIManager.installLookAndFeel("JGoodies Plastic 3D", "com.jgoodies.looks.plastic.Plastic3DLookAndFeel");
UIManager.installLookAndFeel("JGoodies Plastic XP", "com.jgoodies.looks.plastic.PlasticXPLookAndFeel");
}
catch (ClassNotFoundException ignored) { }
}
protected class IdeStarter extends ApplicationStarterEx {
private Splash mySplash;
@Override
public boolean isHeadless() {
return false;
}
@Override
public String getCommandName() {
return null;
}
@Override
public void premain(String[] args) {
initLAF();
}
@Nullable
private Splash showSplash(String[] args) {
if (StartupUtil.shouldShowSplash(args)) {
final ApplicationInfoEx appInfo = ApplicationInfoImpl.getShadowInstance();
final SplashScreen splashScreen = getSplashScreen();
if (splashScreen == null) {
mySplash = new Splash(appInfo);
mySplash.show();
return mySplash;
}
else {
updateSplashScreen(appInfo, splashScreen);
}
}
return null;
}
private void updateSplashScreen(ApplicationInfoEx appInfo, SplashScreen splashScreen) {
final Graphics2D graphics = splashScreen.createGraphics();
final Dimension size = splashScreen.getSize();
if (Splash.showLicenseeInfo(graphics, 0, 0, size.height, appInfo.getSplashTextColor())) {
splashScreen.update();
}
}
@Nullable
private SplashScreen getSplashScreen() {
try {
return SplashScreen.getSplashScreen();
}
catch (Throwable t) {
LOG.warn(t);
return null;
}
}
@Override
public void main(String[] args) {
SystemDock.updateMenu();
// Event queue should not be changed during initialization of application components.
// It also cannot be changed before initialization of application components because IdeEventQueue uses other
// application components. So it is proper to perform replacement only here.
final ApplicationEx app = ApplicationManagerEx.getApplicationEx();
WindowManagerImpl windowManager = (WindowManagerImpl)WindowManager.getInstance();
IdeEventQueue.getInstance().setWindowManager(windowManager);
Ref<Boolean> willOpenProject = new Ref<Boolean>(Boolean.FALSE);
AppLifecycleListener lifecyclePublisher = app.getMessageBus().syncPublisher(AppLifecycleListener.TOPIC);
lifecyclePublisher.appFrameCreated(args, willOpenProject);
LOG.info("App initialization took " + (System.nanoTime() - PluginManager.startupStart) / 1000000 + " ms");
PluginManagerCore.dumpPluginClassStatistics();
if (!willOpenProject.get()) {
WelcomeFrame.showNow();
lifecyclePublisher.welcomeScreenDisplayed();
}
else {
windowManager.showFrame();
}
app.invokeLater(new Runnable() {
@Override
public void run() {
if (mySplash != null) {
mySplash.dispose();
mySplash = null; // Allow GC collect the splash window
}
}
}, ModalityState.NON_MODAL);
app.invokeLater(new Runnable() {
@Override
public void run() {
if (myPerformProjectLoad) {
loadProject();
}
//noinspection SSBasedInspection
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
PluginManager.reportPluginError();
}
});
//safe for headless and unit test modes
UsageTrigger.trigger(app.getName() + "app.started");
}
}, ModalityState.NON_MODAL);
}
}
private void loadProject() {
Project project = null;
if (myArgs != null && myArgs.length > 0 && myArgs[0] != null) {
LOG.info("IdeaApplication.loadProject");
project = CommandLineProcessor.processExternalCommandLine(Arrays.asList(myArgs), null);
}
final MessageBus bus = ApplicationManager.getApplication().getMessageBus();
bus.syncPublisher(AppLifecycleListener.TOPIC).appStarting(project);
}
public String[] getCommandLineArguments() {
return myArgs;
}
public void setPerformProjectLoad(boolean performProjectLoad) {
myPerformProjectLoad = performProjectLoad;
}
}