/* * Moonlight|3D Copyright (C) 2005 The Moonlight|3D team * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Created on Jan 5, 2005 */ package eu.moonlight3d.framework; /** * \package eu.moonlight3d.framework * * This is a container for the core program framework and assorted utilities. * * This package is part of the core program. */ import java.util.logging.Logger; import com.trolltech.qt.gui.QApplication; import com.trolltech.qt.gui.QFont; import com.trolltech.qt.gui.QStyleFactory; import eu.moonlight3d.framework.helper.Property; import eu.moonlight3d.framework.helper.Value; import eu.moonlight3d.framework.localization.L10N; import eu.moonlight3d.framework.preferences.PreferencesGroup; import eu.moonlight3d.framework.tasks.TaskManager; import eu.moonlight3d.framework.ui.ApplicationWindow; import eu.moonlight3d.framework.ui.FrameLayout; import eu.moonlight3d.framework.ui.SplashScreen; import eu.moonlight3d.framework.ui.UIManager; import eu.moonlight3d.framework.ui.UIPalette; /** * This class is the main singleton for Moonlight|3D. All other important * manager and factory classes should be accessed through this singleton * unless they are provided explicitely as arguments. * * @author gregor */ public final class State { /** * True if Moonlight|3D is running without a user interface in batch mode. */ private boolean batchMode; /** * Moonlight|3D command line arguments */ private String[] commandLineArguments; /** * Name of directory where Moonlight|3D is installed */ private String installationDirectory; /** * Reference to single global instance of document manager */ private eu.moonlight3d.framework.document.DocumentManager documentManager; /** * Reference to single global instance of plugin manager */ private eu.moonlight3d.framework.plugins.Manager pluginManager; /** * Reference to single global instance of preferences manager */ private eu.moonlight3d.framework.preferences.Manager preferencesManager; /** * Reference to single instance of main window */ private eu.moonlight3d.framework.ui.ApplicationWindow mainWindow; /** * Reference to single instance of user interface manager */ private eu.moonlight3d.framework.ui.UIManager uiManager; /** * Reference to single global instance of script manager */ private eu.moonlight3d.framework.scripts.Manager scriptManager; /** * Reference to single global background task manager */ private TaskManager taskManager; /** * Application name and version information */ private VersionInformation versionInformation; /** * Short application named used as base name for application directory * and base file name. */ private String applicationShortName; /** * Marker for singleton instance creation */ private static boolean instanceCreated=false; /** * Reference to singleton instance */ private static State instance=null; /** * Default constructor for this class. The real initalisation work is * not done in this constructor, but in initialise(), because only then * getInstance() will work reliably. This constructor is only here * to prevent uncontrolled instantiation of this class. * */ private State() { } /** * Main initialisation for this class. This function is allocating * all classes that are queryable from this singleton. It is called * immediately after constructing this class by getInstance() * */ private void initialise() { documentManager=new eu.moonlight3d.framework.document.DocumentManager(); preferencesManager=new eu.moonlight3d.framework.preferences.Manager(); pluginManager=new eu.moonlight3d.framework.plugins.Manager(); scriptManager=new eu.moonlight3d.framework.scripts.Manager(); taskManager=new TaskManager(); uiManager=new UIManager(); } /** * Start the application. This includes showing the splash screen in * interactive mode, loading preferences and initializing plugins. * * @param args command line arguments as passed to main() * @throws Exception */ public void start(String args[]) throws Exception { /* * args[] contains the full path to Moonlight|3D in the filesystem. * This parameter is only passed to main because there is no way * to determine this in Java and should be treated as internal. * Therefore it is removed from the command line here and treated * separately. */ String[] strippedArgs=new String[args.length-1]; String installDir=args[0]; if(args.length>1) { System.arraycopy(args, 1, strippedArgs, 0, args.length-1); } args=strippedArgs; /* * On Windows, quotation marks around the installation directory * argument are neccessary to protect white spaces in it, but * the Windows shell does not remove them before passing the * argument to the program. Instead, we have to work around that * here. */ if(installDir.charAt(0)=='"') { installDir=installDir.substring(1,installDir.length()-2); } QApplication qApp=new QApplication(args); installationDirectory=installDir; commandLineArguments=args.clone(); L10N.loadTranslations(); logger().info(versionInformation.getApplicationVersionString() + " starting"); if(!batchMode) { SplashScreen.open(); } if(!batchMode) { SplashScreen.setStartupMessage("Loading preferences..."); } preferencesManager.loadPreferences(); if(!batchMode) { SplashScreen.setStartupMessage("Loading plugins..."); } pluginManager.loadPlugins(); PreferencesGroup preferences=new PreferencesGroup(); preferences.setName("GeneralUI"); Property useSystemTheme=new Property(preferences); useSystemTheme.setName("useSystemTheme"); useSystemTheme.setType(Value.Type.Boolean); useSystemTheme.setValue(false); preferencesManager.getCurrentPreferences().addPreferencesGroup(preferences); if(!batchMode) { SplashScreen.setStartupMessage("Applying preferences..."); } preferencesManager.applyLoadedPreferences(); if(!batchMode) { if(useSystemTheme.getBooleanValue()==false) { QApplication.setStyle(QStyleFactory.create("plastique")); QApplication.setPalette(new UIPalette()); QApplication.setFont(new QFont("Trebuchet",8)); } } if(!batchMode) { SplashScreen.setStartupMessage("Running startup scripts..."); } scriptManager.runStartupScripts(); } /** * Run the application interactively. This will open the application's * main window and run the Qt event loop. This function returns when * the last window has been closed. * @throws Exception */ public void runInteractive() throws Exception { SplashScreen.setStartupMessage("Creating main window..."); eu.moonlight3d.framework.ui.propertysheet.PropertySheetDefinition.parsePropertySheetDefinitions(); createMainWindow(); SplashScreen.remove(); getMainWindow().show(); QApplication.exec(); } /** * Shutdown the application. This unloads plugins and writes application * preferences out to the file system. * @throws Exception */ public void shutdown() throws Exception { pluginManager.unloadPlugins(); preferencesManager.updatePreferenceFiles(); } /** * Return whether Moonlight|3D runs in batch mode. If Moonlight|3D runs in * batch mode there must be no attempt to use any user interface functions * and no actions must happen that require user input or user intervention, * because the user interface is not initialised and no user may be present * to react. If Moonlight|3D does not run in batch mode, the full user * interface is available and can be relied upon to interact with the user. * * @return true if Moonlight|3D is in batch mode, false otherwise */ public boolean getBatchMode() { return batchMode; } /** * Internal: set batch mode state upon startup. * * @param batchMode true if Moonlight|3D is running in batch mode, false otherwise */ public void setBatchMode(boolean batchMode) { this.batchMode = batchMode; } /** * Internal: set the command line arguments upon startup. * * @param commandLineArguments the command line arguments as passed to main() */ public void setCommandLineArguments(String[] commandLineArguments) { this.commandLineArguments=commandLineArguments.clone(); } /** * Return the command line arguments that Moonlight|3D has been called with. * This returns the full command line as passed to main() by the Java virtual * machine. * * @return the command line arguments as passed to main() */ public String[] getCommandLineArguments() { return commandLineArguments.clone(); } /** * Internal: set the path where Moonlight|3D is installed. * * @param installationDirectory the Moonlight|3D installation directory */ public void setInstallationDirectory(String installationDirectory) { this.installationDirectory=installationDirectory; } /** * Return the directory into which Moonlight|3D is installed. This * is an absolute path name. * * @return the Moonlight|3D installation directory */ public String getInstallationDirectory() { return installationDirectory; } /** * Return the lifecycle manager singleton * * @return lifecycle manager */ public eu.moonlight3d.framework.document.DocumentManager getDocumentManager() { return documentManager; } /** * Return the plugin manager singleton * * @return plugin manager */ public eu.moonlight3d.framework.plugins.Manager getPluginManager() { return pluginManager; } /** * Return the preferences manager * * @return preferences manager */ public eu.moonlight3d.framework.preferences.Manager getPreferencesManager() { return preferencesManager; } /** * Return the UI manager * * @return UI manager */ public eu.moonlight3d.framework.ui.UIManager getUIManager() { return uiManager; } /** * Create the main window for Moonlight|3D. * * @throws Exception if no {@link FrameLayout} with the name "mainwindow" * is registerd. */ public void createMainWindow() throws Exception { mainWindow=new ApplicationWindow(uiManager.getLayout("mainwindow")); } /** * Return the main window for Moonlight|3D * * @return main application window */ public ApplicationWindow getMainWindow() { return mainWindow; } /** * Return the scripts manager * * @return scripts manager */ public eu.moonlight3d.framework.scripts.Manager getScriptManager() { return scriptManager; } /** * Returns the background task manager * * @return background task manager */ public TaskManager getTaskManager() { return taskManager; } /** * Static accessor method returning the current instance of this class. * This function is reentrant even when the singleton class is constructed * for the first time. * * @return singleton instance */ public static State getInstance() { if(!instanceCreated) { instanceCreated=true; instance=new State(); instance.initialise(); } return instance; } /** * This method is intended for accessing the logger used throughout the application. * @return java.util.Logger instance for the Moonlight|3D application */ public Logger logger() { return Logger.getLogger("Moonlight|3D"); } /** * Wrapper around System.loadLibrary that must be used by plugins that want to load * native libraries. The problem is that classes loaded by our own class loader * cannot currently load native libraries using it. They will get an * UnsatisfiedLinkError stating that Native library ... already loaded in another * classloader. To prevent this, we need to defer the library loading to a class * that has been loaded by the actual system classloader. * * @param library name of native library to load */ public void loadLibrary(String library) { System.loadLibrary(library); } /** * Set the application information and version. * * @param versionInformation the version information to use */ public void setVersionInformation(VersionInformation versionInformation) { this.versionInformation=versionInformation; } /** * Retrieve the application name and version * * @return current application name and version */ public VersionInformation getVersionInformation() { return versionInformation; } /** * Retrieve the version of the Moonlight application framework * that is being used. * * @return version information for the application framework */ public VersionInformation getFrameworkVersionInformation() { return new VersionInformation("Moonlight Application Framework",0,1,0); } /** * Get the short application name (useful for generating file and directory * names based on the application name). * * @return application short name */ public String getApplicationShortName() { return applicationShortName; } /** * Set the short application name. This string should only consist of the * characters [a-zA-Z0-9] so that legal file names can be generated from it. * * @param applicationShortName application short name */ public void setApplicationShortName(String applicationShortName) { this.applicationShortName = applicationShortName; } }