| /* |
| * 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; |
| } |
| } |