/* * 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.ApplicationManager; import com.intellij.openapi.application.ApplicationStarter; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.PathManager; 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(); } 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 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 implements ApplicationStarter { private Splash mySplash; @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 willOpenProject = new Ref(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; } }